2012-10-11 59 views
7

我想到了回收對象的方法時就明白了。我正在做這個實驗,看看內存池是如何工作的,我意識到在99%的情況下這是非常不必要的。在GC銷燬嘗試中保留對象

但是,我有一個問題。有沒有辦法強制GC保留對象?換句話說,我可以告訴GC不要銷燬一個對象,而是說在一個列表中創建了一個新的引用,該列表保存了可供使用的對象?這個問題,雖然我沒有測試過這一點,就是如果我增加一些像這樣的列表:

~myObject() 
{ 
    ((List<myObject>)HttpContext.Current.Items[typeof(T).ToString()]).add(this);//Lets assume this is ASP 
} 

它將一個指針到該對象到列表中,但如果對象被毀滅,那麼我會得到空指針異常,因爲對象不再存在。但是,也許我可以告訴GC不要收集這個項目,從而保持對象?

我知道這是大多數程序員會去的東西的類型,「爲什麼你會這樣做?」。但另一方面,編程則是嘗試新事物和學習新事物。任何建議,想法和實施?任何幫助將不勝感激!

回答

6

是的,這是合法的。它被稱爲「復活」。當您將this引用分配給「活」的某個位置時,則該對象不再被視爲垃圾。

您還需要使用GC.ReRegisterForFinalize(this)重新註冊以進行最終確定,或者下次該對象變爲垃圾時,它不會被終止(析構函數不會被調用)。

您可以在this MSDN Magazine article中閱讀更多關於物體復活的內容。

0

GC只會照顧那些被引用消失的對象,無論是否超出被明確發佈的範圍。

無論採用哪種方式,您都需要查看KeepAliveSuppressFinalize方法,以防止GC垃圾收集您的對象。一旦你真的完成了他們,你需要註冊它們,由收集者使用ReRegisterForFinalize

+0

SuppressFinalize只是取消運行析構函數,而不是集合。 KeepAlive更好,但你必須把它稱爲某個地方,而不是實際的。 –

2

是的,這是可能的,它甚至有一個名稱:復活。

但如果對象被銷燬,我將得到一個空指針異常,因爲對象不再存在。

更糟糕的是,你會得到一個無效的指針(引用)錯誤。可能是藍屏或服務器崩潰。但幸運的是,CLR不會讓這種情況發生。簡單地將一個註定的實例放在任何一種列表中都會使它再次可達,然後它將不會被回收。

當你想讓你的物體多次被回收時,你將不得不打電話給GC.ReRegisterForFinalize(x)

儘管最實際的答案是:不要這樣做。單獨的析構函數會造成相當大的開銷,並且有很多方法可能導致錯誤。