Est-il possible de forcer le garbage collection en Java, même si c'est délicat à faire ? Je connais System.gc();
y Runtime.gc();
mais ils suggèrent seulement de faire GC. Comment puis-je forcer le GC ?
Réponses
Trop de publicités?Une autre option consiste à ne pas créer de nouveaux objets.
Mise en commun d'objets est éloigné pour réduire le besoin de GC en Java.
La mise en commun des objets n'est généralement pas plus rapide que la création d'objets (surtout pour les objets légers), mais elle est plus rapide que la collecte des déchets. Si vous créez 10 000 objets et que chaque objet fait 16 octets. Cela fait 160 000 octets que GC doit récupérer. D'un autre côté, si vous n'avez pas besoin des 10 000 objets en même temps, vous pouvez créer un pool pour recycler/réutiliser les objets, ce qui élimine le besoin de construire de nouveaux objets et élimine le besoin de GC des anciens objets.
Quelque chose comme ceci (non testé). Et si vous voulez que ce soit thread safe, vous pouvez remplacer la LinkedList par une ConcurrentLinkedQueue.
public abstract class Pool<T> {
private int mApproximateSize;
private LinkedList<T> mPool = new LinkedList<>();
public Pool(int approximateSize) {
mApproximateSize = approximateSize;
}
public T attain() {
T item = mPool.poll();
if (item == null) {
item = newInstance();
}
return item;
}
public void release(T item) {
int approxSize = mPool.size(); // not guaranteed accurate
if (approxSize < mApproximateSize) {
recycle(item);
mPool.add(item);
} else if (approxSize > mApproximateSize) {
decommission(mPool.poll());
}
}
public abstract T newInstance();
public abstract void recycle(T item);
public void decommission(T item) { }
}
Nous pouvons déclencher jmap -histo:live <pid>
en utilisant le runtime java. Cela forcera une GC complète sur le tas pour marquer tous les objets vivants.
public static void triggerFullGC() throws IOException, InterruptedException {
String pid = ManagementFactory.getRuntimeMXBean().getName().split("@")[0];
Process process = Runtime.getRuntime().exec(
String.format("jmap -histo:live %s", pid)
);
System.out.println("Process completed with exit code :" + process.waitFor());
}
Vraiment, je ne te comprends pas. Mais pour être clair à propos de "Création d'objets infinis" Je voulais dire qu'il y a un morceau de de code dans mon gros système qui fait la création de d'objets qui ont des handles et qui vivent dans mémoire, je n'ai pas pu obtenir ce morceau de code en fait, juste un geste ! !!
C'est correct, seulement le geste. Vous avez à peu près les réponses standards déjà données par plusieurs posters. Prenons les choses une par une :
- Je n'ai pas pu obtenir ce morceau de code en fait
Correct, il n'y a pas de jvm réel - tel est seulement une spécification, un tas de science informatique décrivant un comportement désiré ... J'ai récemment étudié l'initialisation d'objets Java à partir de code natif. Pour obtenir ce que vous voulez, le seul moyen est de faire ce qu'on appelle un nulling agressif. Les erreurs, si elles sont mal faites, sont si graves que nous devons nous limiter à la portée originale de la question :
- un morceau de code dans mon grand système création d'objets
La plupart des personnes présentes ici supposeront que vous dites que vous travaillez sur une interface. Dans ce cas, il faudrait voir si l'on vous remet l'objet entier ou un élément à la fois.
Si vous n'avez plus besoin d'un objet, vous pouvez lui assigner null mais si vous vous trompez, une exception pour pointeur nul est générée. Je parie que vous pouvez réaliser un meilleur travail si vous utilisez NIO
Chaque fois que vous ou moi ou n'importe qui d'autre obtient : " S'il vous plaît, j'en ai horriblement besoin. "Il s'agit d'un précurseur presque universel de la destruction presque totale de ce sur quoi vous essayez de travailler ..... Écrivez-nous un petit échantillon de code, en enlevant tout code réel utilisé et montrez-nous votre question.
Ne soyez pas frustré. Souvent, cela se résume à ce que votre administrateur de bases de données utilise un paquet acheté quelque part et que la conception originale n'est pas adaptée aux structures de données massives.
C'est très courant.
Si vous manquez de mémoire et que vous obtenez le message OutOfMemoryException
vous pouvez essayer d'augmenter la quantité d'espace de tas disponible pour java en démarrant votre programme avec java -Xms128m -Xmx512m
au lieu de seulement java
. Cela vous donnera une taille de tas initiale de 128 Mo et une taille maximale de 512 Mo, ce qui est bien plus que les 32 Mo/128 Mo standard.