2012-09-28 89 views
5

給定下面的代碼。私人領域的垃圾收集

class A { 
    private B b; 
    public A() { 
     b = new B(); 
    } 
} 

class Main { 
    public static void main(String[] args) { 
     A a = new A(); // two objects are created (a and b) 
     // <-- is B object, referenced only by private a.b eligible for garbage collection? 
     keepAlive(a); 
    } 
} 

創建A對象後,B對象是否可以被垃圾收集?

回答

6

我覺得不行,因爲這個字段仍然可以通過反射訪問(使用setAccessible(true))。

理論上,編譯器可以證明,此字段將永遠不會被訪問,它將使B符合垃圾收集(從JLS 12.6.1 Implementing Finalization):

可達的對象是可以在任何可能訪問的任何目標從任何活動線程繼續計算。優化程序的轉換可以設計爲將可達到的對象數量減少到小於天真被認爲可達的對象數量。例如,編譯器或代碼生成器可以選擇將不再用於空的變量或參數設置爲使得此類對象的存儲器可以更快地被回收。

但我不認爲在實踐中編譯器和JVM是智能

1

@Kuba你的意思是:可以B類的領域A類的實例ab實例被垃圾收集?不是,而a不是null,因爲ba引用。

1

不,因爲主線程的路徑爲ba

0

標準的編譯器不是那麼聰明。

class A 
{ 
    private Object[] array; 

    public A() 
    { 
     array = new Object[10000000]; 
    } 
} 

public static void main(String[] args) 
{ 
    LinkedList<A> list = new LinkedList<A>(); 
    while (true) 
    { 
     list.add(new A()); 
    } 
} 

此代碼拋出內存異常後,極少數的循環,所以答案原來的問題肯定是否定的。