在.NET中,finalize和dispose有什么区别?

15

可能重复:
Finalize vs Dispose

你好,

最近我在面试中被问到 finalize 和 dispose。它们各自何时使用以及垃圾回收器与它们有什么关系。请分享更多关于这个主题的链接。

请分享...

提前致谢。


那你没有得到工作邀请吗?这个问题在任何一本关于C#或CLR的书中都有涉及。 - Hans Passant
我回答了这个问题,但当面试官问到我们显式实现Dispose时会发生什么,GC的作用以及Finalize的位置是什么时,我感到很困惑。 - HotTester
2个回答

17

1
我认为“非确定性”是这里正确的词。 - Steven Sudit
@Steven,我英语很差。谢谢你指出这一点。 - Darin Dimitrov
那么如果开发人员实现了IDisposable,GC是否仍会调用Finalize? - HotTester
不,你的英语完全可以理解。我只是对确切的词语有些挑剔。 - Steven Sudit
请注意,当没有更多的引用指向对象时,垃圾回收器并不会调用终结器,而是在第一次尝试释放对象时调用。 - Guffa
显示剩余3条评论

17
Finalizers在一个对象有资格被回收之前,由垃圾回收运行。Dispose()用于清理非托管资源,如网络连接、文件、操作系统句柄等。它与using块一起使用效果最佳,编译器确保一旦完成对象的使用,就会立即调用Dispose(),并确保一旦对象被处理,就不能再使用它。
注意,finalizers不一定会运行,因此依赖它可能是危险的:

对您的影响:您的程序不能依靠终结器来保持事物的整洁。终结器是一个安全网,而不是主要的资源回收手段。当您完成一个资源时,需要通过调用Close或Disconnect或对象上可用的任何清理方法来释放它。 (IDisposable接口规范了这个约定。)

小心对象何时变得可收集。请阅读上面链接的文章-它既不是作用域(一个与对象生命周期无关的奇怪单词 - 它是“程序文本区域,在其中可以使用其未经限定名称引用[命名实体]的合法区域。”),也不是严格的引用计数,因为对象甚至可以在最后一个引用消失之前就变得可收集。

2
我想补充一点,Finalizers 应该谨慎使用。当你为对象添加 finalizer 时,你会导致运行时至少保留该对象两个 GC 循环。此外,在 finalizer 中,不能保证对象的任何成员未被回收。因此,访问它们可能会导致运行时异常。 - taylorjonl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接