126 votes

Quand System.gc() fait-il quelque chose ?

Je sais que le ramassage des ordures est automatisé en Java. Mais j'ai compris que si vous écrivez System.gc() dans votre code, la VM Java peut décider ou non, au moment de l'exécution, d'effectuer un ramassage des déchets à ce moment-là. Comment cela fonctionne-t-il précisément ? Sur quelle base/avec quels paramètres exactement la VM décide-t-elle de faire (ou de ne pas faire) une GC lorsqu'elle voit un objet de type System.gc() ? Existe-t-il des exemples dans lesquels il est une bonne idée de mettre cela dans votre code ?

2voto

lwpro2 Points 5331

On ne peut jamais forcer le garbage collection. System.gc ne fait que suggérer la vm pour la collecte des déchets, cependant, personne ne sait vraiment à quel moment le mécanisme s'exécute, c'est ce qu'indiquent les spécifications JSR.

2voto

Kyune Points 21

Il y a beaucoup à dire sur le fait de prendre le temps de tester les différents paramètres de collecte des déchets, mais comme nous l'avons mentionné plus haut, il n'est généralement pas utile de le faire.

Je travaille actuellement sur un projet impliquant un environnement à mémoire limitée et une quantité relativement importante de données - il y a quelques gros morceaux de données qui poussent mon environnement à sa limite, et même si j'ai pu réduire l'utilisation de la mémoire de sorte qu'en théorie, tout devrait bien fonctionner, je recevais toujours des erreurs d'espace de tas - les options GC verbeuses m'ont montré qu'il essayait de faire un garbage collect, mais en vain. Dans le débogueur, je pouvais exécuter System.gc() et, bien sûr, il y avait "beaucoup" de mémoire disponible... pas beaucoup de mémoire supplémentaire, mais suffisamment.

Par conséquent, le seul moment où mon application appelle System.gc() est lorsqu'elle est sur le point d'entrer dans le segment de code où les grands tampons nécessaires au traitement des données seront alloués, et un test sur la mémoire libre disponible indique que je ne suis pas assuré de l'avoir. En particulier, j'ai devant moi un environnement de 1 Go où au moins 300 Mo sont occupés par des données statiques, la majeure partie des données non statiques étant liées à l'exécution, sauf lorsque les données traitées font au moins 100-200 Mo à la source. Tout cela fait partie d'un processus de conversion automatique des données, de sorte que les données existent toutes pendant des périodes relativement courtes à long terme.

Malheureusement, bien que des informations sur les différentes options de réglage du ramasseur de déchets soient disponibles, il semble que ce processus soit en grande partie expérimental et que les détails de bas niveau nécessaires pour comprendre comment traiter ces situations spécifiques ne soient pas faciles à obtenir.

Cela dit, même si j'utilise System.gc(), j'ai continué à utiliser les paramètres de la ligne de commande et j'ai réussi à améliorer le temps de traitement global de mon application de façon relativement importante, même si je n'ai pas réussi à surmonter l'obstacle que représente le fait de travailler avec des blocs de données plus importants. Ceci étant dit, System.gc() est un outil....a très peu fiable, et si vous ne faites pas attention à la façon dont vous l'utilisez, vous souhaiterez plus souvent qu'autrement qu'il ne fonctionne pas.

2voto

Shervin Points 8675

Si vous voulez savoir si votre System.gc() est appelé, vous pouvez, avec la nouvelle mise à jour 4 de Java 7, recevoir une notification lorsque la JVM effectue une collecte d'ordures.

Je ne suis pas sûr à 100% que le GarbageCollectorMXBean a été introduite dans la mise à jour 4 de Java 7, car je n'ai pas pu la trouver dans les notes de mise à jour, mais j'ai trouvé l'information dans le fichier d'aide aux utilisateurs de Java 7. javaperformancetuning Site .com

1voto

mataal Points 318

En bref :

Les paramètres dépendent de la VM.

Exemple d'utilisation - je n'en vois pas pour les applications d'exécution/production, mais il est utile de l'exécuter pour certains harnais de profilage, comme appeler

// test run #1
test();
for (int i=0; i<10; i++) { 
// calling repeatedly to increase chances of a clean-up
  System.gc(); 
}
// test run #2
test();

0voto

zxcv Points 1682

Je ne peux pas penser à un exemple spécifique où il est bon d'exécuter une GC explicite.

En général, l'exécution d'une GC explicite peut en fait causer plus de mal que de bien, car une GC explicite déclenche une collecte complète, qui prend beaucoup plus de temps car elle passe en revue chaque objet. Si cette GC explicite finit par être appelée de manière répétée, l'application pourrait facilement être lente car beaucoup de temps est passé à exécuter des GC complètes.

Alternativement, si vous passez en revue le tas avec un analyseur de tas et que vous soupçonnez un composant de bibliothèque d'appeler des GC explicites, vous pouvez les désactiver en ajoutant : gc=-XX:+DisableExplicitGC aux paramètres de la JVM.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X