2014-02-13 31 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