垃圾回收:是否有必要在Dispose方法中将大对象设置为null?
实现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方法,所有那些资源都将被释放。
我认为,空值浮动比"僵尸"对象浮动更有害。