调用Dispose不会清理对象C#使用的内存?

时间:2014-02-06 12:40:39

标签: c# garbage-collection

一个人告诉我,Dispose用于运行用户定义的代码,释放不会自动释放的资源 - 如文件句柄,网络句柄,数据库连接等。

GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();

他也说

注意,.NET垃圾收集器非常难以预测,它可能会在清理所有符合收集条件的旧实例之前创建一个对象的几个实例。一种确定的方法(不依赖于内存分析器)就是在终结器中放置一个断点。

我通过上面的GC相关代码释放内存并收集所有无人认领的对象或对象超出范围。

他也表示从不在生产环境中使用上述GC相关代码,但没有解释原因....所以请告诉我如果有人使用以下GC相关代码GC.Collect(); {{1 }}

无论如何都在寻找深入的知识。感谢

1 个答案:

答案 0 :(得分:1)

只要在终结器中手动执行,

GC就不会调用Dispose方法

GC的工作流程非常简单,但很多人都感到困惑,让我们把东西放到他们的位置

DisposeGC无关。 Dispose是一个在接口IDisposable中定义的方法,与其他接口一样,类可以实现该方法并为用户提供调用该方法的能力。 GC根本不关注这个界面。    一旦我们在.NET中进行自动内存管理,并且我们知道GC可以很好地完成其工作,并且它会自动清除所有托管资源,因此没有理由提供用户Dispose方法来清除托管资源。因此,通常Dispose用于清除非托管资源,但没有人会阻止您取消订阅全局事件作为示例,或者为嵌套对象调用Dispose(请注意,全局事件几乎总是不好的做法:))

另一方面,GC知道Finalizer,如果Finalizer存在,则GC将对象处置推迟到下一次收集,并在清除前致电Finalizer记忆。要在一个位置使用处理代码,程序员通常会创建Dispose(bool)并从FinalizerIDisposable.Dispose方法调用此方法。在这里,您需要注意,如果调用来自Finalizer,则不允许您访问受管资源,因为GC不保证任何处置顺序,并且资源可能已处于无效状态。这称为dispose pattern

关于生产中的GC调用,是的,不建议再次使用,因为GC通常做得很好,而且由于GC.Collect操作很昂贵,所以在我们决定自动收集之前没有理由打扰GC引擎