我什么时候应该使用 GC.SuppressFinalize()?
在.NET中,什么情况下应该使用GC.SuppressFinalize()?
使用此方法给我带来什么好处?
In .NET, under which circumstances should I use GC.SuppressFinalize()
?
What advantage(s) does using this method give me?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
SuppressFinalize
只能由具有终结器的类调用。 它通知垃圾收集器 (GC)this
对象已被完全清理。当您拥有终结器时,推荐的
IDisposable
模式是:通常,CLR 在创建对象时会使用终结器对其进行标记(使创建它们的成本更高)。
SuppressFinalize
告诉 GC 该对象已正确清理,不需要进入终结器队列。 它看起来像一个 C++ 析构函数,但其行为却一点也不像。SuppressFinalize
优化并非微不足道,因为您的对象可以在终结器队列上等待很长时间。 不要试图对您提醒的其他对象调用SuppressFinalize
。 这是一个即将发生的严重缺陷。设计指南告诉我们,如果您的对象实现了
IDisposable
,则不需要终结器,但如果您有终结器,则应该实现IDisposable
以允许对类进行确定性清理。大多数时候,您应该能够使用
IDisposable
来清理资源。 仅当您的对象持有非托管资源并且需要保证这些资源被清理时,您才应该需要终结器。注意:有时,程序员会添加终结器来调试自己的
IDisposable
类的构建,以测试代码是否已正确处理其IDisposable
对象。SuppressFinalize
should only be called by a class that has a finalizer. It's informing the Garbage Collector (GC) thatthis
object was cleaned up fully.The recommended
IDisposable
pattern when you have a finalizer is:Normally, the CLR keeps tabs on objects with a finalizer when they are created (making them more expensive to create).
SuppressFinalize
tells the GC that the object was cleaned up properly and doesn't need to go onto the finalizer queue. It looks like a C++ destructor, but doesn't act anything like one.The
SuppressFinalize
optimization is not trivial, as your objects can live a long time waiting on the finalizer queue. Don't be tempted to callSuppressFinalize
on other objects mind you. That's a serious defect waiting to happen.Design guidelines inform us that a finalizer isn't necessary if your object implements
IDisposable
, but if you have a finalizer you should implementIDisposable
to allow deterministic cleanup of your class.Most of the time you should be able to get away with
IDisposable
to clean up resources. You should only need a finalizer when your object holds onto unmanaged resources and you need to guarantee those resources are cleaned up.Note: Sometimes coders will add a finalizer to debug builds of their own
IDisposable
classes in order to test that code has disposed theirIDisposable
object properly.SupressFinalize
告诉系统在终结器中应该完成的任何工作都已经完成,因此不需要调用终结器。 来自 .NET 文档:一般来说,大多数
Dispose()
方法都应该能够调用GC.SupressFinalize()
,因为它应该清理将在终结器中清理的所有内容。SupressFinalize
只是提供一种优化,使系统不必费心将对象排队到终结器线程。 正确编写的Dispose()
/finalizer 无论是否调用GC.SupressFinalize()
都应该正常工作。SupressFinalize
tells the system that whatever work would have been done in the finalizer has already been done, so the finalizer doesn't need to be called. From the .NET docs:In general, most any
Dispose()
method should be able to callGC.SupressFinalize()
, because it should clean up everything that would be cleaned up in the finalizer.SupressFinalize
is just something that provides an optimization that allows the system to not bother queuing the object to the finalizer thread. A properly writtenDispose()
/finalizer should work properly with or without a call toGC.SupressFinalize()
.如果对象有终结器,.net 会将引用放入终结队列中。
由于我们调用了
Dispose(true)
,它清除了对象,因此我们不需要终结队列来完成这项工作。因此,调用 GC.SuppressFinalize(this) 删除终结队列中的引用。
If object has finalizer, .net put a reference in finalization queue.
Since we have call
Dispose(true)
, it clear object, so we don't need finalization queue to do this job.So call
GC.SuppressFinalize(this)
remove reference in finalization queue.如果一个类或从它派生的任何东西可能会使用终结器保存对对象的最后一个实时引用,则
GC.SuppressFinalize(this)
或GC.KeepAlive(this)
code> 应该在任何可能受到该终结器不利影响的操作之后对对象调用,从而确保终结器在该操作完成之前不会运行。在任何没有终结器的类和有终结器的类中,
GC.KeepAlive()
和GC.SuppressFinalize(this)
的成本本质上是相同的一般应该调用GC.SuppressFinalize(this)
,因此使用后一个函数作为Dispose()
的最后一步可能并不总是必要的,但也不会出错。If a class, or anything derived from it, might hold the last live reference to an object with a finalizer, then either
GC.SuppressFinalize(this)
orGC.KeepAlive(this)
should be called on the object after any operation that might be adversely affected by that finalizer, thus ensuring that the finalizer won't run until after that operation is complete.The cost of
GC.KeepAlive()
andGC.SuppressFinalize(this)
are essentially the same in any class that doesn't have a finalizer, and classes that do have finalizers should generally callGC.SuppressFinalize(this)
, so using the latter function as the last step ofDispose()
may not always be necessary, but it won't be wrong.该方法必须在实现 IDisposable 的对象的 Dispose 方法上调用,这样,如果有人调用该方法,GC 就不会再次调用终结器处置方法。
请参阅:GC.SuppressFinalize(Object) 方法 - Microsoft Docs
That method must be called on the
Dispose
method of objects that implements theIDisposable
, in this way the GC wouldn't call the finalizer another time if someones calls theDispose
method.See: GC.SuppressFinalize(Object) Method - Microsoft Docs