所有类型都有从Object继承的Finalize方法



我们知道,当一个类型重写Finalize方法时,它必须在垃圾收集中幸存下来,它会被提升到另一代,迫使对象的生存时间比它应该的要长得多。这在内存消耗方面并不理想,这就是为什么您应该尽可能避免最终确定的原因。

但是,这不是所有类型都是从Object隐式派生的吗?而Object确实有一个默认的Finalize方法,所以CLR应该考虑所有类型都有Finalize方式,因此堆上的所有对象都会被提示进行新生成,并比它们应该的生存时间更长?

正如@conton7在一条评论中所说,运行时足够聪明,可以知道如果实例的继承链中除了Object.Finalize之外没有终结器,那么它就不必标记实例进行终结。文件的相关部分是:

Object类不提供Finalize方法的实现,垃圾收集器也不会标记从Object派生的类型以进行终结,除非它们重写Finalize方法。

有趣的是,C#规范和ECMACLI规范都没有强制执行这种行为。允许运行时的一致性实现始终调度所有对象以完成。然而,正如您在问题中认识到的那样,这将导致垃圾收集的巨大开销,因此这是不切实际的。


注意:相关章节为C#规范的§8.9和§15.2以及ECMA CLI规范的I.8.9.6.7。

最新更新