2014-05-25 6 views
1

Je ne peux pas comprendre ce qui se passe iciGarbage Collector sortie inattendue

public class UnderstandGC { 
public class Inner1 
{ 
    String name=new Inner2().name; 
    public void finalize() 
    { 
     System.out.println("Inner1 -> I am Dead"); 
    } 
} 
public class Inner2 
{ 
    public String name="Inner2"; 
    public void finalize() 
    { 
     System.out.println("Inner2 -> I am Dead"); 
    } 
} 
public void finalize() 
{ 
    System.out.println("Main -> I am Dead"); 
} 
    public static void main(String[] args) { 
     UnderstandGC ugc=new UnderstandGC(); 
Inner1 inner1=ugc.new Inner1(); 
//System.out.println("hello");  //1 

Runtime.getRuntime().gc();   


    } 
} 

Résultats escomptés: Inner2 -> I am Dead bcoz objet de Inner2 instancié comme référence sur le terrain dans Inner1 n'a pas de références locales de la pile principale d'exécution de fil.

Sortie Observé: rien

L'observation intéressante est de savoir si j'inclure un commentaire //1 dans mon code il fonctionne très bien. Je ne peux pas comprendre ce qui se passe.

Répondre

1

Les gc() method javadoc états

appel à cette méthode suggère que la machine virtuelle Java effort vers dépenser le recyclage des objets inutilisés afin de rendre la mémoire qu'ils occupent actuellement disponibles pour une réutilisation rapide.

Il n'y a aucune garantie qu'il exécutera le GC dans les deux cas.

+0

D'accord avec la déclaration mais cela fonctionne à chaque fois si j'ajoute // 1. Je me suis testé plus de 10 fois. – user2653926

+1

@ user2653926 Cela peut être dû à la façon dont votre JVM est implémentée. L'écriture sur une sortie standard peut provoquer cela. Un million d'autres choses peuvent le provoquer aussi. Vous ne devriez pas en dépendre, jamais. –

+0

OK dernière question "IS Println auto flush" cela signifie que cela se produit de façon synchrone – user2653926

0

Testé par adjonction

Runtime.getRuntime().gc();  
    for(int i=0;i<25000;i++){ 

    } 

Sur mon tout JVM moins de 25000 sur la boucle, ne remet pas le gc, il semble même pas donner une chance pour la machine virtuelle Java pour appeler le gc, même si ça le voulait aussi. Je spécule que le System.out.println donne à la JVM juste assez de temps pour appeler le gc (encore une fois, seulement s'il le veut aussi car il n'est pas garanti), avant que l'application se termine.

+0

C'est quelque chose que je ne peux pas comprendre si println est synchrone .. comment donne-t-il l'heure? Votre instruction est vraie pour // 1 après avoir appelé gc() et cela fonctionne aussi mais pour // 1 avant gc, l'explication est pas satisfaisant – user2653926

+0

Le gc est un thread de démon indépendant, tandis que l'application exécute l'instruction println que gc appelle. –