在.NET中,在什么情况下应该使用GC.SuppressFinalize()
使用此方法有什么好处?
发布于 2008-09-29 23:56:04
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);
}
}通常,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发布于 2008-09-29 22:44:22
SupressFinalize告诉系统,在终结器中完成的所有工作都已经完成,因此不需要调用终结器。从.NET文档中:
实现IDisposable接口的
对象可以从IDisposable.Dispose方法调用此方法,以防止垃圾回收器对不需要此方法的对象调用Object.Finalize。
一般来说,几乎任何Dispose()方法都应该能够调用GC.SupressFinalize(),因为它应该清理终结器中要清除的所有内容。
SupressFinalize只是提供了一种优化,允许系统不必费心将对象排队到终结器线程。无论是否调用GC.SupressFinalize(),正确编写的Dispose()/finalizer都应该正常工作。
发布于 2018-04-16 09:54:03
Dispose(true);
GC.SuppressFinalize(this);如果对象有终结器,.net会将一个引用放入终结器队列中。
因为我们已经调用了Dispose(true),它清除了对象,所以我们不需要finalization队列来完成这项工作。
因此调用GC.SuppressFinalize(this) remove reference in finalization队列。
https://stackoverflow.com/questions/151051
复制相似问题