2011-06-14 65 views
2

也許這是一個愚蠢的問題。
當一個對象被標記爲垃圾收集時,java是否也標記了包含垃圾收集的對象?java是否遞歸執行GC?

我的意思是,

class ContainerClass { 
    ContainedClass obj1, obj2; 
    //Constructor 
    ContainerClass() { 
    obj1 = new ContainedClass(); 
    obj2 = new ContainedClass(); 
    } 
    // main 
    public static void main(String args[]) { 
     ContainerClass c = new ContainerClass(); 
     c = null ; // c is mared for GC. The question is c.obj1 and c.obj2 is also marked? 
    } 
} 
+0

較長的答案[here](http ://chaoticjava.com/posts/how-does-garbage-collection-work/)... :-) – 2011-06-14 09:00:53

+0

檢查包含的鏈接:http://java.sun.com/j2se/reference/whitepapers/memorymanagement_whi雅氏.pdf – 2011-06-14 09:07:10

回答

5

是的,如果只對象ContainerClass有它們的引用,那麼ContainedClass對象將成爲在同一時刻的ContainerClass對象本身有資格進行垃圾回收。

注意,這些對象的實際收集可以獨立發生。

+0

雅。我假設「ONLY」容器類具有對象引用。 – raj 2011-06-14 09:02:30

0

專人爲您例如:是的,包含的對象將被標記爲GC,但不能,因爲容器收集。他們被標記,因爲容器不見了,沒有其他對象持有對ContainedClass實例的引用。

所以一般來說,不,這不是遞歸。如果可以收集,每個實例都會單獨進行測試。 包含的實例不是容器類的一部分,它們過着自己的生活。容器只是擁有某種指針。

1

一個目的是準備被垃圾收集如果沒有活動線程保持的對象的引用了,直接或間接地。所以,是的,包含的對象也準備好垃圾收集。

2

你的問題在某些方面是回到前面。對象沒有標記爲收集,而是標記爲保留。

垃圾收集器標誌着這仍然在使用,從活性的堆棧幀和所有靜態變量等,以下找到引用的對象。垃圾收集器發現的每個對象都被標記爲正在使用中,並且不會被收集。

所以子對象未標記爲收藏,而不是他們只是沒有標明保持,因爲他們的父對象不是非此即彼。

(這是馬克的千真萬確和掃垃圾收集這是大多數的JVM的默認設置。其他垃圾收集器的行爲可能不同。)

0

的Java是否執行GC遞歸?

不是一個體面的垃圾收集器不使用簡單的遞歸進行標記。如果是這樣,那麼標記長鏈表將需要標記算法使用非常深的堆棧來標記它。這將是一個重大問題。

有許多是GC實現者可以使用,以避免過多的遞歸策略:

  • 其實你不使用遞歸。您使用標記堆棧和迭代算法...更節省空間。
  • 技巧可用於深遍歷列表時,儘量減少堆棧深度...如果你知道那裏的深度;例如這是next字段。
  • Knuth和Boehm-Demers-Weiser有處理溢出標記堆棧的方法,涉及溢出堆棧然後拾取塊。
  • Deutsch-Schorr-Waite算法使用指針反轉,因此根本沒有標記堆棧。
  • 等等。

如果您想了解更多詳細信息,由理查德·瓊斯和拉斐爾林斯,1996年參考"Garbage Collection: Algorithms for Automatic Dynamic Memory Management"(有理查德·瓊斯,安東尼·霍斯金,並且由於今年晚些時候艾略特莫斯稱爲"The Garbage Collection Handbook: The Art of Automatic Memory Management"一個新的GC書!!)

(Nit挑選:GC不標記垃圾收集對象,它標記爲非垃圾...並丟棄未標記的對象。)