2013-01-11 161 views
0

我對Java中垃圾收集的工作方式有點困惑。什麼觸發java垃圾收集器

我得到一個對象有資格進行垃圾回收時沒有更多的實時引用,但如果它有活動對象的引用呢?

可以說我有節點的集合,再次引用多個節點

List 
1 -> Node a -> Node b 
2 -> Node c -> Node d 
3 -> Node d -> Node c 
4 -> Node e 
5 

現在,如果我刪除列表,節點C d和e應該被垃圾收集。節點e不再有對它的引用,並且節點c和d具有循環引用。

但是Node a呢?它會被垃圾收集?

無論節點b是否有外部活動引用,它會不同嗎?說如果節點b從一個不同的地方引用它,這會使節點停留在內存中嗎?

+1

可以收集任何沒有來自線程根的強*參考的對象。這意味着兩個對象可以相互引用,但會被收集。你可以對對象有一個弱引用,但它仍然可以被清理。 –

回答

4

存在引用的根集(當前局部變量,靜態引用,堆棧幀的操作數堆棧),這被認爲是實時的。任何無法從此根引用集訪問的內容都有資格進行垃圾回收。

節點a沒有任何引用指向它。因此,即使它指的是一個活動對象,它也有資格使用gc。由於節點b具有實時參考,因此它不會被gc化。

+1

我推薦Brian Goetz撰寫的這兩篇優秀文章:[垃圾收集簡史](http://www.ibm.com/developerworks/java/library/j-jtp10283/)和[HotSpot JVM垃圾收集] (http://www.ibm.com/developerworks/java/library/j-jtp11253/)。 –

0

GC知道哪些對象處於活動狀態,因爲它會將所有活動對象複製到新的內存區域,下次所有未複製的對象都將被覆蓋。

請注意,這對於Oracle VM中GC的當前實現有效。其他虛擬機可以以另一種方式處理它。

2

如果節點B有其他任何對它的引用,那麼對於節點A的垃圾收集無關緊要。如果節點A沒有對它的引用,它將被垃圾回收。節點B將保留,因爲它仍然有實時參考。

基本上,沒有實時引用它的每個對象都將被收集。包含在這些對象中的任何對象都將受到同樣的機制,如果沒有其他引用,它們也將被垃圾收集。如果有其他對象的實時引用,它們將保留。