This文章说
如果一个对象有一个终结器,那么当它没有被立即删除时 垃圾收集器决定它不再“活”。相反,它变成了 一种特殊的root,直到.NET调用终结器方法。 这意味着这些对象通常需要多个垃圾 要从内存中删除的集合,因为它们将在第一个中存活 他们被发现未被使用的时间。
我的问题是,当GC发现无法再引用对象并立即收集对象时,为什么不调用终结器?为什么它需要的不仅仅是垃圾收集?
答案 0 :(得分:5)
要考虑两点:
终结器可能需要一些时间才能完成。例如,它可能最终关闭资源或类似的东西。你不希望它成为垃圾收集时间的一部分,这可能阻止线程做工作(当他们只想获得一些内存时)。通过单独运行完成,GC本身可以非常快速地完成,并且最终确定工作可以与其他工作同时完成。
终结者可以通过让对象再次可见来复活对象 - 但是检测到(我怀疑)还需要另外扫描内存......所以为什么不等到下一次它会发生?
答案 1 :(得分:2)
因为(取决于所选的GC模式)执行GC it has to pause key parts of the runtime时。因此,您希望尽可能快。这会产生两个问题:
要解决这两个问题,那些具有待处理终结器的问题将排队,然后在 GC完成后(运行时工作时)执行。
作为旁注,最好将终结器与IDisposable
结合起来并让Dispose()
取消最终确定;这样,它不需要在以后完成,并且可以一步清理。
答案 2 :(得分:0)
当.net垃圾收集器运行时,对象分为三类:可从“普通”有根引用访问的对象,任何有根引用无法访问的对象,以及对象任何“正常”的有根引用都无法访问它们,但要么在它们被放弃时请求接收通知,或者可以从已经这样做的其他对象接收。垃圾收集器在第三类中创建对象列表;该列表存储为有根引用,使其中的所有对象“生效”。但是,系统会遍历该列表中的项目,取消其“通知”请求,运行Finalize()方法,并将其从列表中删除。如果在完成所有操作之后没有对该对象的引用存在,那么该对象将在下一个GC循环中被声明为“死”。