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

时间:2020-03-05 18:49:25  来源:igfitidea点击:

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

解决方案

回答

如果类具有Dispose方法,则最佳做法是调用它。原因
其背后是Dispose在调用时运行,而将对象设置为
null只是将一个条目添加到GC中的Finalize队列中,而我们不能
确定GC何时运行。

在仅使用托管资源(例如数组)的类型上实现Dispose方法不会带来性能优势,因为垃圾回收器会自动回收这些资源。主要在使用本机资源的托管对象和公开给.NET Framework的COM对象上使用Dispose方法。使用本机资源(例如FileStream类)的托管对象实现IDisposable接口。

引入的一种优雅的Dispose方法是使用" using"构造。对于可能不熟悉该构造的我们来说,它提供了一种方法,即使在操作期间引发异常,也可以在实现IDisposable的实例上隐式调用Dispose()。以下是using构造的示例:

using(DisposableClass dc = new DisposableClass()) 
{ 
   dc.PerformActionOnUmanagedResources(); 
   dc.PerformAnotherActionOnUmanagedResources(); 
}

在上一个示例中,如果在PerformActionOnUmanagedResources()方法中引发了异常,尽管将不处理PerformAnotherActionOnUmanagedResources()方法,但using块仍将隐式调用dc上的Dispose方法,以确保任何非托管资源的真实性。

回答

dispose方法的目的是通过调用基类dispose方法来释放与类以及父类相关的所有资源。阅读此链接,它应该使事情变得更加清晰:

http://msdn.microsoft.com/zh-CN/library/fs2xkftw.aspx

回答

你所说的"大物体"是什么意思?

但是,至少应在实现IDisposable的任何成员上调用Dispose()。

回答

通常不行。

垃圾收集器会寻找根对象,如果两个对象都不是根对象,则循环依赖关系不会阻止收集。

有一个警告:如果对象A引用了对象B,并且正在处理对象B,则我们可能希望清理这种关系,否则可能会导致泄漏。这种情况最常见的地方是在事件处理程序中(A-> B的引用是B所控制的,因为它预订了A上的事件)。在这种情况下,如果A仍然扎根,则即使B被处置也无法收集。

回答

正如其他人指出的那样,这不是必需的,但这是一种好习惯,并且有助于调试。

一旦对象完成使用指针,然后将其设置为null有助于防止以后对该对象的重用(我们将获得null引用异常)。

一旦删除了C ++析构函数中的成员指针,将逻辑设置为null。无需这样做,但以后可以进行故障排除。

回答

仔细考虑一下Disposable方法的用途:通常是因为我们持有一些在垃圾回收期间不会释放的资源。这通常类似于数据库连接或者文件句柄。因此,一旦调用Dispose方法,所有那些资源都将被释放。

我认为,空值浮动比"僵尸"对象浮动更有害。