2014-02-13 24 views
1

根據this answer由合理可靠的來源,在C#中,一旦GC可以證明它不再被使用,即使對它的引用仍然存在,也可以收集對象。這可能會導致令人驚訝的早期完成問題。拖延收集對象

如果您特意要延遲收集對象直到某個點,那麼最好的方法是什麼?我們不能通過簡單地保持對象的引用來實現,如果我們試圖簡單地使用引用來停止GC,那麼這些操作可能會被優化掉。我們可以做什麼?

(此問題的動機是Java中的an older question,其中有人希望確保在WeakReference按其指示對象排序時不會收集WeakReference列表的指示對象,因此,解釋了Java行爲是在這種情況下,類似或不同的C#的和Java中的相應問題的解決方案也會理解)

+0

'static' variables ....? –

+0

不完全確定,但使用析構函數可能有助於在某些情況下?據我所知,它會延遲收集對象,因爲它期望析構函數來完成這項工作。 – HOKBONG

回答

1

你可以考慮GCHandle.Alloc防止管理對象被收集。

http://msdn.microsoft.com/en-us/library/a95009h1%28v=vs.110%29.aspx

當不再需要GCHandle時,請不要忘記撥打電話Free

object obj = ....; 
GCHandle handle = GCHandle.Alloc(obj); 
// .... 
// object o is protected from garbage collection 
// .... 
handle.Free(); 

注意(http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.gchandle.free%28v=vs.110%29.aspx

調用者必須確保對於給定的手柄,免費只調用 一次。

+0

這看起來很像我正在尋找的東西,但我不確定是否限制對象必須只有blittable成員是一個問題。 – user2357112

+0

嗯......我想這個限制是針對'Pinned'句柄的,參見http://msdn.microsoft.com/en-us/library/83y4ak54%28v=vs.110%29.aspx。但是要創建一個'Pinned'句柄,使用另一個重載:'GCHandle.Alloc(object,GCHandleType)'。簡單的'GCHandle.Alloc(object)'使用'GCHandleType == Normal'。 – AlexD