Sam*_*ron 274 .net c# garbage-collection idisposable suppressfinalize
在.NET中,我应该在哪种情况下使用GC.SuppressFinalize()?
使用这种方法有什么好处?
Rob*_*son 286
SuppressFinalize只能由具有终结器的类调用.它通知垃圾收集器(GC)this完全清理了对象.
有终结器时推荐的IDisposable模式是:
public class MyClass : IDisposable
{
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// called via myClass.Dispose().
// OK to use any private object references
}
// Release unmanaged resources.
// Set large fields to null.
disposed = true;
}
}
public void Dispose() // Implement IDisposable
{
Dispose(true);
GC.SuppressFinalize(this);
}
~MyClass() // the finalizer
{
Dispose(false);
}
}
Run Code Online (Sandbox Code Playgroud)
通常,CLR在创建对象时会使用终结器对对象进行标记(使创建成本更高).SuppressFinalize告诉GC该对象已正确清理,无需进入终结器队列.它看起来像一个C++析构函数,但不会像一个人那样行事.
SuppressFinalize优化并不简单,因为您的对象可以在终结器队列上等待很长时间.不要试图在其他物体上调用SuppressFinalize.这是一个等待发生的严重缺陷.
设计指南告诉我们,如果您的对象实现了IDisposable,则不需要终结器,但如果您有终结器,则应实现IDisposable以允许确定性地清理您的类.
大多数情况下,您应该能够使用IDisposable来清理资源.当对象保留在非托管资源上并且需要保证清理这些资源时,您应该只需要一个终结器.
注意:有时编码器会添加一个终结器来调试自己的IDisposable类的构建,以便测试代码是否正确处理了它们的IDisposable对象.
public void Dispose() // Implement IDisposable
{
Dispose(true);
#if DEBUG
GC.SuppressFinalize(this);
#endif
}
#if DEBUG
~MyClass() // the finalizer
{
Dispose(false);
}
#endif
Run Code Online (Sandbox Code Playgroud)
Mic*_*urr 37
你告诉系统,在终结器中完成的任何工作都已经完成,所以不需要调用终结器.从.NET文档:
实现IDisposable接口的对象可以从IDisposable.Dispose方法调用此方法,以防止垃圾收集器在不需要它的对象上调用Object.Finalize.
通常,大多数Dispose()方法都应该能够调用GC.SupressFinalize(),因为它应该清理在终结器中清理的所有内容.
SupressFinalize只是提供一种优化,允许系统不打扰将对象排队到终结器线程.无论是否调用GC.SupressFinalize(),正确编写的Dispose()/终结器都可以正常工作.
小智 6
Dispose(true);
GC.SuppressFinalize(this);
Run Code Online (Sandbox Code Playgroud)
如果对象有终结器,.net 会将引用放入终结队列中。
由于我们有 call Dispose(true),它清除了对象,所以我们不需要终结队列来完成这项工作。
因此调用GC.SuppressFinalize(this)删除终结队列中的引用。