48 votes

Les Références circulaires en Java

Donné une agrégation d'instances de la classe qui se rapportent les uns aux autres dans un complexe, circulaire, de la mode: est-il possible que le garbage collector peut ne pas être en mesure de libérer ces objets?

J'ai vaguement rappeler ce un problème dans la JVM dans le passé, mais je pensais que cela a été résolu il y a des années. pourtant, certains d'enquête dans jhat a révélé une référence circulaire être la raison d'une fuite de mémoire que je suis maintenant confronté.

Note: j'ai toujours eu l'impression que la JVM a été capable de résoudre les références circulaires et de libérer de ces "îles de déchets" de la mémoire. Toutefois, je me pose cette question juste pour voir si quelqu'un a trouvé des exceptions.

42voto

David G Points 3588

Seulement une très naïve de mise en œuvre aurait un problème avec les références circulaires. Wikipédia a un bon article sur les différents algorithmes de GC. Si vous voulez vraiment en savoir plus, essayez (Amazon) de Collecte des Ordures: les Algorithmes Automatiques pour la Gestion Dynamique de la Mémoire . Java a eu une bonne garbage collector depuis la version 1.2 et une exceptionnellement bonne en 1.5 et Java 6.

La partie la plus difficile pour l'amélioration de la GC est de réduire les pauses et les frais généraux, et non pas des choses de base comme référence circulaire.

23voto

Rob Walker Points 25840

Le garbage collector sait où sont les objets racines: statique, les habitants sur la pile, etc, et si les objets ne sont pas accessibles à partir d'une racine puis ils seront remis en état. S'ils sont accessibles, ils doivent rester dans les parages.

12voto

Alexander Points 4298

Ryan, à en juger par votre commentaire http://stackoverflow.com/questions/176745/circular-references-in-java#176767, vous êtes tombé dans le piège de la référence à des objets d'une classe, qui a probablement été chargé par le bootstrap/système de chargeur de classe. Chaque classe est référencé par le chargeur de classe qui a chargé la classe, et peut donc être récupérées uniquement si le chargeur de classe n'est plus accessible. Le hic, c'est que le bootstrap/système de chargeur de classe n'est jamais nettoyée, par conséquent, les objets accessibles depuis les classes chargées par le système de chargeur de classe ne peuvent pas être récupérées soit.

La raison de ce comportement est expliqué dans JLS. Par exemple, la Troisième Édition de 12,7 http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.7.

4voto

Uri Points 50687

Si je me souviens bien, alors, selon le cahier des charges, il y a seulement des garanties à propos de ce que la JVM ne peuvent pas collecter (ou quelque chose d'accessible), et non pas ce qu'il percevra.

Sauf si vous travaillez en temps réel avec la Jvm, plus moderne éboueurs devraient être en mesure de traiter des dossiers complexes structures de référence et d'identifier des "sousgraphes" qui peuvent être éliminés en toute sécurité. L'efficacité, le temps de latence, et la probabilité de le faire s'améliorer au fil du temps à mesure que la recherche des idées font leur chemin dans la norme (plutôt que sur la recherche) VMs.

3voto

Thilo Points 108673

Non, au moins à l'aide du Soleil officiel de la JVM, le garbage collector sera en mesure de détecter ces cycles et de libérer de la mémoire, dès qu'il n'y a plus aucune référence à partir de l'extérieur.

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