2009-11-01 56 views
1

這是一個.net CLR相關問題。.net CLR相關問題

我有3個對象的對象A,B,C

甲refres B和B是指Ç

如果我殺對象碰巧這些對象在堆中什麼 「A」 explicitly.Which將是垃圾收集?(對象A或B或C或全部?)

有人可以在這種情況下詳細解釋垃圾收集過程。

在此先感謝 SNA

+0

你怎麼殺A? – 2009-11-01 09:04:22

回答

9

首先 - 你不能 「殺對象 」A「 明確」;你可以清除對它的引用,但是這只是設置一個局部變量爲null,並且與託管堆上的實際對象無關。你可以Dispose()吧,但那是沒有什麼跟GC有關。

這一切都取決於;可以別的看到B/C?如果不是,他們是合格收集。但GC是非確定性的;它只在選擇時纔會發生。在某些未確定的時間內,GC將啓動,檢測到這些對象無法訪問,並將其刪除。在這個過程中,它將檢查是否有終結者(仍然未完成),並執行終結者(分兩步處理)。

人們經常在可達性方面忘記的一件事是事件;如果B/C訂閱長壽命對象上的事件,則可以訪問B/C(由事件發佈者)。


澄清; GC通過從根對象(線程等)構建樹來工作。它每走,標記所有可以到達的對象。任何未在最後標記的內容都有資格收集。這避免了COM/COM +由於斷開數據島而導致內存泄漏的問題,其中X => Y且Y => X(因此X和Y都具有正的參考計數,因此都不被清除)。

1

第一個誤解可能是你不能明確地殺死一個託管對象。

您可以釋放自己分配的非託管內存,但這不是託管內容,也不受垃圾回收的限制。

當您將對A的引用設置爲null或超出範圍時,則不會有任何對B & C的引用,並且下一個GC集合將負責處理它。

1

在.NET中,沒有辦法實際殺死/刪除一個對象。你可以明確地做的是拋棄一個對象。這只不過是對對象的簡單調用Dispose()。這將允許你清理你的對象,然後再由垃圾收集器收集它(你不能真正的富裕)。有關更多詳細信息,請參閱IDisposable。第二個選項是在GC收集之前有機會清理您的對象,以實現finalizer。與Dispose()不同,它將自動被GC調用。同樣,這兩種方法都是在對象可能停止存在之前清除所有資源的方法。

所以要回答你的問題,如果你的對象A被「殺死」,只有當它沒有被任何其他對象引用時,纔會發生B和C將被「殺死」,如果它們只通過A被引用。通常你會這對實際發生的時間沒有任何影響。你所能做的就是實現終結器,以便在事件發生時得到通知。 GC是一個後臺服務,在一個單獨的線程上運行,該線程在實際刪除對象時遵循複雜的邏輯。

如果你想了解GC的工作原理,我會建議以下twoarticles。雖然有點老,但他們仍然完全適用。