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 ?
Réponses
Trop de publicités?En pratique, il généralement décide de faire un garbage collection. La réponse varie en fonction d'un grand nombre de facteurs, comme la JVM sur laquelle vous vous exécutez, le mode dans lequel elle se trouve et l'algorithme de ramassage des déchets qu'elle utilise.
Je ne dépendrais pas de cela dans votre code. Si la JVM est sur le point de lancer une erreur OutOfMemoryError, appeler System.gc() ne l'arrêtera pas, parce que le ramasseur d'ordures tentera de libérer autant qu'il le peut avant d'en arriver à cette extrémité. La seule fois où je l'ai vu utilisé en pratique est dans les IDE où il est attaché à un bouton sur lequel l'utilisateur peut cliquer, mais même là, il n'est pas terriblement utile.
Vous n'avez aucun contrôle sur la GC en Java - la VM décide. Je ne suis jamais tombé sur un cas où System.gc() est nécessaire . Étant donné que l'appel System.gc() ne fait que SUGGÉRER à la VM d'effectuer un ramassage des déchets et qu'il effectue également un ramassage COMPLET (anciennes et nouvelles générations dans un tas multigénérationnel), il peut en fait consommer PLUS de cycles de processeur que nécessaire.
Dans certains cas, il peut être judicieux de suggérer à la VM d'effectuer une collecte complète MAINTENANT, car vous savez peut-être que l'application restera inactive pendant les prochaines minutes avant que les opérations lourdes ne soient effectuées. Par exemple, juste après l'initialisation d'un grand nombre d'objets temporaires pendant le démarrage de l'application (par exemple, je viens de mettre en cache une tonne d'informations et je sais que je n'aurai pas beaucoup d'activité pendant une minute ou deux). Pensez à un IDE tel qu'eclipse qui démarre - il fait beaucoup d'initialisation, donc peut-être qu'immédiatement après l'initialisation, il est logique de faire un gc complet à ce moment-là.
La spécification du langage Java ne garantit pas que la JVM démarre une GC lorsque vous appelez System.gc()
. C'est la raison de ce "peut ou ne peut pas décider de faire un GC à ce moment-là".
Maintenant, si vous regardez Code source d'OpenJDK qui est l'épine dorsale de la JVM d'Oracle, vous verrez qu'un appel à System.gc()
lance effectivement un cycle GC. Si vous utilisez une autre JVM, telle que J9, vous devez consulter leur documentation pour trouver la réponse. Par exemple, la JVM d'Azul a un garbage collector qui fonctionne en permanence, donc un appel à System.gc()
ne fera rien
D'autres réponses mentionnent le lancement d'un GC dans JConsole ou VisualVM. En gros, ces outils font un appel distant à System.gc()
.
En général, vous ne souhaitez pas lancer un cycle de collecte des déchets à partir de votre code, car cela perturbe la sémantique de votre application. Votre application effectue des opérations commerciales, la JVM s'occupe de la gestion de la mémoire. Vous devez garder ces deux préoccupations séparées (ne faites pas faire à votre application de la gestion de la mémoire, concentrez-vous sur l'activité).
Cependant, il y a peu de cas où un appel à System.gc()
pourrait être compréhensible. Prenons, par exemple, les microbenchmarks. Personne ne souhaite qu'un cycle GC se produise au milieu d'un microbenchmark. Vous pouvez donc déclencher un cycle GC entre chaque mesure pour vous assurer que chaque mesure commence avec un tas vide.
Vous devez être très prudent si vous appelez System.gc(). L'appeler peut ajouter des problèmes de performance inutiles à votre application, et il n'est pas garanti qu'il effectue réellement une collecte. Il est en fait possible de désactiver le recours explicite à System.gc() via l'argument java "-XX:+DisableExplicitGC".
Je vous recommande vivement de lire les documents disponibles à l'adresse suivante Java HotSpot Garbage Collection pour plus de détails sur le ramassage des déchets
- Réponses précédentes
- Plus de réponses