Combien d’objects seront éligibles à la récupération de place après avoir exécuté “m1 = null; m2 = null; ”?

Je suis confus de comprendre après avoir exécuté m1 = null; m2 = null; . Combien d’objects seront éligibles à la récupération de place?

 public class MyTest { MyTest m; void show() { System.out.println("Hello this is show method."); } public static void main(Ssortingng args[]) { MyTest m1 = new MyTest(); MyTest m2 = new MyTest(); MyTest m3 = new MyTest(); m1.m = m2; m2.m = m3; m3.m = m1; m1 = null; m2 = null; // Question here: How many objects will be eligible for garbage collection? } } 

Zéro.

Le diagramme de référence d’object ressemble à ceci:

Circulaire

Vous pouvez voir que la référence est circulaire. Une référence de main à m3 maintient l’object m3 vie. À son tour, m3 maintient en vie m1 , qui conserve le m2 de GC.

Notez que si vous définissez m3 sur null , les trois objects deviendraient éligibles au GC à la fois, malgré les références circulaires existantes pour chacun d’eux. GC est assez intelligent pour comprendre que toutes les références proviennent d’objects éligibles au GC, et collectent les trois.

Potentiellement tous les trois. Aucune variable n’étant référencée après le marqueur // , l’optimiseur a le droit de les supprimer du cadre à ce stade.

Voila! GC ne recueillera rien ici! Voyons ce qui se passe réellement ici. Lorsque vous avez créé trois objects de m1 , m2 et m3 de MyTest , l’object a été créé comme ci-dessous (par exemple, l’ID de référence de l’object commence à 410):

 m1 MyTest (id=410) m null m2 MyTest (id=412) m null m3 MyTest (id=414) m null 

Lorsque vous initialisez

 m1.m = m2; m2.m = m3; m3.m = m1; 

Les objects ressemblent maintenant à:

 m1 MyTest (id=410) m MyTest (id=412) m2 MyTest (id=412) m MyTest (id=414) m3 MyTest (id=414) m MyTest (id=410) m MyTest (id=412) m MyTest (id=414) m MyTest (id=410) . . . (This is circular) 

Mais après avoir réinitialisé m1 et m2 sur null , les objects ressemblent à:

 m1 null m2 null m3 MyTest (id=414) m MyTest (id=410) m MyTest (id=412) m MyTest (id=414) m MyTest (id=410) . . . 

Regardez, m1 et m2 sont maintenant null , mais leurs références sont toujours vivantes en m3 !

Aucun comme ils sont encore tous accessibles par la référence circulaire que vous construisez là par m3