垃圾回收:在Dispose方法中是否有必要将大对象设置为null?

7

在实现Dispose()方法时,是否有必要将大对象设置为null

6个回答

5
如果一个类有Dispose方法,最佳实践是调用它。原因在于,当调用Dispose时,它会运行,而将对象设置为null只是将条目添加到GC的Finalize队列中,我们无法确定GC何时运行。
对于仅使用托管资源(如数组)的类型实现Dispose方法没有性能优势,因为它们会被垃圾回收器自动回收。主要在使用本机资源的托管对象和公开给.NET Framework的COM对象上使用Dispose方法。使用本机资源的托管对象(如FileStream类)实现IDisposable接口。
一种优雅的调用Dispose的方式是使用“using”结构。对于那些可能不熟悉该结构的人,它提供了一种隐式调用实现IDisposable的实例的Dispose()的方法,即使在操作期间抛出异常也是如此。以下是使用结构的示例:
using(DisposableClass dc = new DisposableClass()) 
{ 
   dc.PerformActionOnUmanagedResources(); 
   dc.PerformAnotherActionOnUmanagedResources(); 
} 

在前面的例子中,如果在PerformActionOnUmanagedResources()方法中抛出异常,尽管PerformAnotherActionOnUmanagedResources()方法不会被处理,但是使用块仍将隐式调用dc上的Dispose方法,确保释放任何未受管理的资源。

5

通常情况下不会。

垃圾回收器会寻找根对象,如果两个对象都没有被引用,则循环依赖关系不会阻止回收。

但是有一个例外:如果对象A引用了对象B,并且对象B正在被处理,您可能需要清理该关系,否则可能会导致泄漏。这种情况最常见于事件处理程序(从A到B的引用是B控制的,因为它订阅了A上的事件)。在这种情况下,如果A仍然被引用,即使B已经被处理,它也无法被回收。


事件和Dispose并没有真正相关。如果您所说的“disposed”是指“回收”,那么您是正确的,但否则您的措辞不太清楚。 - Brian Rasmussen
关于引用,为这个答案添加一个(晚期的)警告; 只有极少数情况会导致泄漏,而大多数被“认可”的泄漏实际上并不是。这篇 MSDN 博客有一个非常好的解释:http://blogs.msdn.com/b/davidklinems/archive/2005/11/16/493580.aspx - Russ Clarke

3

1

“大对象”指的是什么?

无论如何,你都应该在任何实现IDisposable接口的成员上调用Dispose()方法。


1

正如其他人指出的那样,这并不是必需的,但这是一个好的实践方法,有助于调试。

一旦对象完成了它正在使用的指针,将其设置为 null 可以帮助防止稍后重用该对象(您将收到 null 引用异常)。

相同的逻辑适用于在 C++ 析构函数中将成员指针设置为 null,一旦您删除了它们。这不是必须的,但它可以帮助以后进行故障排除。


0
想一想 Disposable 方法的目的:通常是因为你持有某些资源,在垃圾回收期间不会被释放。这通常是像数据库连接或文件句柄之类的东西。因此,一旦调用了 Dispose 方法,所有这些资源都已被释放。
我认为,让空值漂浮比让“僵尸”对象漂浮更有害。

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