.NET 最终概念问题
与 dispose 相比,不使用 Finalize 真的更好吗? dispose 是否会在第一次解析时删除非托管资源?
什么是抑制 Finalize ?
Is it really better not to use finalize compare to dispose ? Does dispose remove unmanaged resource in first parse ?
What is suppressing finalize ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
IDisposable 的实现应该是:
如果一个对象有终结器,则 CLR 在终结队列中保留对其的引用。如果您手动处置对象(调用 Dispose()),您已经删除了非托管资源(因为 dispose 的实现和终结器是共享的),因此无需调用终结器,您可以安全地从终结中删除该对象队列(调用 GC.SuppressFinalize(this))。
Your implementation of IDisposable should be:
If an object has a finalizer the CLR keeps a reference to it in the finalization queue. If you dispose manually the object (calling Dispose()) you already remove the unmanaged resources (as the implementation of dispose and the finalizer is shared), so there is no need to call the finalizer and you can safely remove the object from the finalization queue (calling GC.SuppressFinalize(this)).
我写了一篇博客文章 如何实现 IDisposable 和 Finalizers: 3 条简单规则,详细描述了何时以及如何使用每条规则。我还有一些关于该主题的问答。
关于如何实现 IDisposable(以及相应的 FxCop 规则)的臭名昭著的 Microsoft 文档已经过时了。它们确实准确地描述了 Microsoft 如何在 .NET 1.0 中实现 IDisposable...。当 v2.0 发布时,BCL 中的几乎所有类都进行了改造,以遵循与我的博客文章中描述的类似的准则(唯一的区别是 Microsoft 确实 具有受保护的
Dispose( bool)
用于设计用作基类的类)。特别是,据我所知,没有 BCL 类同时负责托管和非托管资源。I wrote a blog post How to Implement IDisposable and Finalizers: 3 Easy Rules that describes in a fair amount of detail when and how to use each. I also have a few Q&As on the subject.
The infamous Microsoft documentation on how to implement
IDisposable
(and the corresponding FxCop rule) are horribly outdated. They do accurately describe how Microsoft implementedIDisposable
... in .NET 1.0. When v2.0 came out, almost all classes in the BCL were retrofitted to follow guidelines similar to the ones described in my blog post (the only difference is that Microsoft does have the protectedDispose(bool)
for classes designed for use as base classes). In particular, no BCL class to my knowledge is responsible for both managed and unmanaged resources.通常,Dispose 和 Finalize 都会清除所有非托管资源(例如句柄)。当 GC 检测到某个对象不再使用时,会发生以下两种情况之一。最好的情况是,如果对象不需要最终确定(它没有非托管资源或称为抑制最终确定),那么它就会立即被清理。最坏的情况是,它被放入另一个区域来存放需要最终确定的内容,并且寿命更长(更长时间地保留那些非托管资源),直到最终终结器运行并且对象已被完全清理。
拥有大量需要最终确定的对象会显着影响性能。处置有两个目的:它返回非托管资源,并抑制终结器(假设您已经正确实现了处置),这给 GC 带来了休息。尽管如此,人们可能会忘记调用 Dispose(或使用 using),因此终结器必须存在。只是尽量不要依赖它。
Typically both Dispose and Finalize will clean up any unmanaged resources (eg handles.) When the GC detects that an object is no longer in use, one of two things happens. Best case, if the object doesn't need to be finalized (it has no unmanaged resources or someone called suppress finalize) then it is cleaned up right then. Worst case, it gets put into another area for things that need to finalized, and lives longer (hanging on to those unmanaged resources longer) until eventually the finalizer runs and the object has been completely cleaned up.
Having a lot of objects that need finalizing can impact performance significantly. Disposing serves two purposes: it gives back the unmanaged resources, and it suppresses the finalizer (assuming you've implemented Dispose correctly) which gives the GC a break. Still, people might forget to call Dispose (or to use a Using) so the finalizer must exist. Just try not to rely on it.