垃圾回收:当对象不再被引用时,GC 回收对象使用的内存。
Dispose:IDisposable 接口中的一种方法,当程序员调用它时(直接或间接通过 using 块)释放所有托管和非托管资源。
Finalizer:释放所有非托管资源的方法。在回收内存之前由 GC 调用。
托管资源:任何实现IDisposable
接口的 .NET 类,如 Streams 和 DbConnections。
非托管资源:包裹在托管资源类中的填充物。Windows 句柄是最简单的例子。
现在回答你的问题:
GC 保留所有对象的列表(终结队列),其类声明了终结器(C# 中的 ~ClassName)。对象在创建时被放入此队列。GC 会定期运行以检查是否有任何对象无法从程序中访问。然后它检查是否有任何不可访问的对象从终结队列中被引用,并将它们放入另一个称为 Freacheable 队列的队列中,而其余的则被回收。一个单独的线程用于运行 Freacheable 队列中对象的 Finalize 方法。
下次 GC 运行时,它会发现之前在 Freacheable 队列中的一些对象已经被 Finalized 准备好进行回收。请注意,GC 至少需要两个周期(如果有很多 Finalization 要做,则需要更多周期)才能使用 Finalizer 处理掉一个对象,这会导致一些性能损失。
该SuppressFinalize
方法只是在对象标头中设置一个标志,指示不必运行终结器。这样 GC 可以立即回收对象的内存。根据上面的定义,该Dispose
方法与终结器(以及更多)执行相同的操作,因此如果执行它,则不再需要终结器。使用该SuppressFinalize
方法,您可以通过将这一事实通知给 GC 来节省一些工作。此外,现在您不必在 Finalizer 中实施检查以避免双重释放。唯一的问题Dispose
是它不能保证运行,因为调用它是程序员的责任,这就是为什么有时我们需要使用终结器。
话虽如此,您很少需要编写终结器,因为对于绝大多数常见的非托管资源,托管包装器已经存在,并且托管资源将通过Dispose
从您自己的Dispose
方法调用它们的方法来释放,只有从那里!在终结器中,您绝不能调用 Dispose 方法。
进一步阅读: