防止CLR中早期垃圾收集的最佳方法

时间:2010-04-27 21:44:59

标签: garbage-collection clr

我编写了一个包含非托管C ++对象的托管类,但我发现 - 在C#中使用它时 - 在我对对象执行方法时,GC会提前启动。我已经阅读了垃圾收集以及如何防止垃圾收集提前发生。一种方法是使用“using”语句来控制何时放置对象,但这会将责任放在托管对象的客户端上。我可以添加到托管类:

MyManagedObject::MyMethod() {

System::Runtime::InteropServices::GCHandle handle =
   System::Runtime::InteropServices::GCHandle::Alloc(this);

// access unmanaged member

handle.Free();

}

System::Runtime::InteropServices::GCHandle handle = System::Runtime::InteropServices::GCHandle::Alloc(this); // access unmanaged member handle.Free(); 这似乎有效。作为.NET的新手,其他人如何处理这个问题?

谢谢,

约翰

2 个答案:

答案 0 :(得分:3)

您可能希望看一下这篇文章:http://www.codeproject.com/Tips/246372/Premature-NET-garbage-collection-or-Dude-wheres-my。我相信它完全描述了你的情况。简而言之,补救措施是using阻止或GC.KeepAlive。但是,我同意在许多情况下,您不希望将此负担传递给非托管对象的客户端;在这种情况下,在每个包装器方法结束时调用GC.KeepAlive(this)是一个很好的解决方案。

答案 1 :(得分:2)

如果要保持终结器不被调用,可以在方法体中使用GC.KeepAlive(this)。正如其他人在评论中正确指出的那样,如果在方法调用期间您的this引用不存在,则可以调用终结器并在调用期间回收内存。

有关详细的案例研究,请参阅http://blogs.microsoft.co.il/blogs/sasha/archive/2008/07/28/finalizer-vs-application-a-race-condition-from-hell.aspx