web-dev-qa-db-fra.com

Collecte de déchets Java

Java appelle automatiquement garbage collector, alors pourquoi avons-nous besoin d'appels manuels pour garbage collection? Quand faut-il utiliser System.gc ()

36
Nageswaran

Java appelle automatiquement garbage collector, alors pourquoi avons-nous besoin d'appels manuels pour garbage collection? 

Nous n'avons pas besoin d'eux. En effet, dans la plupart des cas, l'appel de System.gc() est préjudiciable aux performances des applications. Voir ma réponse à "Pourquoi est-ce une mauvaise pratique d'appeler system gc" pour une explication détaillée.

Quand faut-il utiliser System.gc ()

Si l'application sait qu'elle entre dans une phase où elle n'a rien d'autre à faire ET qu'il est peu probable que l'utilisateur remarque un garbage collection, il est peut-être bon d'appeler System.gc() pour tenter d'empêcher l'utilisateur dans le futur de faire une pause. 

Les inconvénients comprennent:

  • L'appel de System.gc() déclenche généralement un CPG complet qui prend beaucoup plus de temps qu'un CPG du «nouvel espace».
  • L’utilisateur peut réellement s’occuper de/avis. Par exemple, si vous appelez System.gc() entre "niveaux" dans une partie, le chargement du niveau suivant prend plus de temps. 
  • En forçant le CPG, vous obligez la machine virtuelle Java à utiliser des cycles de processeur supplémentaires, etc., qui risquent d'interférer avec les opérations de {autres} _ que l'utilisateur effectue sur sa machine.

(Il peut également exister des raisons légitimes d'appeler System.gc() lors des tests unitaires et lors du débogage du système.)

43
Stephen C

Il n'est pas nécessaire d'appeler explicitement le garbage collection et appeler System.gc() n'est qu'un suggestion, la machine virtuelle Java peut ignorer votre suggestion.

Les seules utilisations pratiques auxquelles je peux penser sont

  1. Lors du débogage, forcer une collection peut exposer une fuite de mémoire
  2. Si le programme passe par des cycles prévisibles de calcul intense suivi d'aucun calcul (comme un jeu basé sur tour par tour), pendant la période sans calcul, la CPU pourrait être utilisée pour un ramassage des déchets suggéré afin d'éviter la gigue pendant les parties de calcul intenses.
14
Tim Bender

System.gc () n'est qu'une suggestion. Mais cela a du sens dans certaines situations.

Supposons que vous ayez la classe MyClass et que vous vous demandiez combien de mémoire utilise une instance. Voici ce que vous pouvez faire (en gros):

MyClass [] objects= new MyClass[100000];
System.gc();
long memoryNow = Runtime.getRuntime().freeMemory();
for (int i = 0; i < 100000; i ++) {
  objects[i] = new MyClass();
}
System.gc();
long memoryLater = Runtime.getRuntime().freeMemory();
int objectSize = (int)((memoryLater - memoryNow) / 100000);

Il y a d'autres cas similaires que j'ai trouvés utiles à System.gc ().

4
iluxa

Le ramasse-miettes est toujours appelé par la machine virtuelle Java lorsque la mémoire est insuffisante pour allouer de nouveaux objets au tas. Lors de l'appel du ramasse-miettes, il respecte les normes Stop the World et appelle pour cela la méthode System.gc().

N'oubliez pas non plus que la machine virtuelle Java exécute également des threads gc parallèles pour supprimer les objets inutilisés de la mémoire. Donc, tout et chaque minute, la machine virtuelle Java maintient une mémoire de tas et tente toujours de ne pas la surcharger. Il n'est donc pas nécessaire d'appeler explicitement la méthode System.gc() ou Runtime.gc().

Si vous voulez plus de détails à ce sujet, vous pouvez obtenir ici pour les informations pertinentes.

1
Ishant

Un aspect qui n’a pas encore été mentionné est que certains types d’objets peuvent demander à des entités extérieures d’agir en leur nom (par exemple, en leur donnant un accès exclusif à une ressource non fongible comme un fichier), au détriment d’autres entités. Lors de la collecte des ordures, le système libérera non seulement la mémoire précédemment occupée par des objets inaccessibles, mais appellera également finalize sur les objets qu'il a avisés d'avoir été abandonnés, permettant ainsi à ces objets d'avertir des entités extérieures que leurs services ne sont plus nécessaires. Il est tout à fait possible qu'un programme atteigne un état où il y a beaucoup de mémoire, mais une ressource nécessaire n'est pas disponible car un objet a obtenu un accès exclusif et a depuis été abandonné sans le libérer. Forcer le ramasse-miettes à fonctionner dans une telle situation peut parfois libérer la ressource nécessaire.

1
supercat

Le processus de récupération de place n'est pas sous le contrôle de l'utilisateur. Il n'est donc pas logique d'appeler explicitement System.gc();. Cela entièrement _ dépend de la machine virtuelle Java. 

Il y a quelques jours, j'avais posé exactement la même question: [Ici]

En fait, de nombreuses questions relatives à l’appel de System.gc(); explicitement ont déjà été posées et sont traitées ici. L'appel explicite de System.gc(); est toujours considéré comme une compétence de programmation médiocre, bien que cela ne fasse pas de mal. 

Voici les quelques liens que vous devriez parcourir. Cela clarifiera définitivement votre doute. 

PS: Btw, vous devriez prendre au sérieux le extra effort à effectuer questions similaires StackOverflow avant de poster sur vos doutes.

0
sgokhales

Il n'est pas nécessaire d'appeler System.gc() ou Runtime.getRuntime().gc(). La machine virtuelle Java contrôle en interne le garbage collection si elle constate qu’elle manque de mémoire.

0
Ritesh Kaushik