2011-12-13 344 views
10

如果一個對象沒有被任何其他引用,那麼它將被.NET CLR垃圾收集器收集。垃圾收集如何收集自我引用對象?

但是,如果objA引用objBobjB引用objCobjC參考回到objA,如何垃圾收集得知他們(作爲一個整體)可以收集?

+2

.NET使用一個[標記和清除算法(http://stackoverflow.com/questions/2344240/what-is-relation-between-gc-finalize-and-dispose)。 –

+0

哦,是的,尋找根,我應該考慮一下! – athos

+0

我不知道,但我會假設它使用某種樹型的東西,任何未連接到主樹的東西永遠不能從主樹訪問(我正在談論的是當前的代碼在堆棧中的某個地方)。我不知道具體情況,但我肯定會解決這個問題。 :) – Chris

回答

7

CLR使用稱爲標記和清除的技術。

作爲該技術的一部分,每一個對象可以被認爲是最初被標記爲收藏。然後,CLR遍歷每個可訪問的對象,以全局變量(靜態字段等)作爲根,並清除每個可移動對象上的標記。然後掃描剩下的標記物體。

請記住,這個「標記」是概念性的;實際上,這些對象很可能被添加到收藏集中。

在循環的自我引用的對象的情況下,對物體沒有提及會從應用程序中找到,因此該算法將永遠達不到這些對象,以「取消標記」他們。

2

GC擁有所有創建的對象的列表。在garbarge過程中,它從全局根(像靜態字段)開始,遍歷每個引用的對象。所有未被擊中的物品都可以被銷燬。

如果沒有辦法打objA,objB或objC,所有這些對象將被收集

+1

不,GC不具備所有創建的對象的列表... – Guffa

+0

@Guffa:它是如何找到需要收集那麼如果它不具有的一切準備一個列表中的對象?標記和掃描描述肯定意味着它確實... – Chris

+0

Chris:GC實際上並不「標記」對象;它是一個概念性構造。實際上,GC **可以訪問被標記爲負數的對象。換句話說,想象一下存在於所有對象上的虛構屬性,稱爲「標記」。 'mark'默認是true,所以GC只需要標記它可以**訪問false的對象。 –