在阅读有关GC的3本书时,我注意到一些奇怪的事实:
C#通过CLR
CriticalFinalizerObject
: CLR以非常特殊的方式处理此类及其派生的类
什么???
“没有找到足够的内存来编译一个方法?”恕我直言 - 代码应该已经编译了......不是吗?
当我编写c#代码时 - 整个代码在运行之前被编译为IL ...不是吗? 但根据文本 - 在 RUNTIME - 他可能找不到足够的内存用于编译 ......
帮助?
答案 0 :(得分:5)
JIT编译器仅在第一次执行时在运行时编译从IL到本机代码的方法。正如您所料,这需要额外的内存。因此,正常的终结器只能在清理线程执行之前编译。
从CriticalFinalizerObject
派生的对象立即编译了终结器,因此在程序关闭时不需要额外的内存来执行它。这适用于必须执行终结器的对象(尽管有断电或类似情况)
答案 1 :(得分:2)
我认为它是'编译器'的后端。从IL到机器代码。
答案 2 :(得分:1)
使用编译器是JIT编译器,它意味着急切地编译终结器方法,而不是在执行之前不久延迟编译。
背后的深层原因是在执行所有正常终结器之后,在应用程序关闭期间调用这些终结器。但CLR确实执行所有挂起的终结器,超时时间为2秒(至少这是因为.NET 2.0从那以后没有检查过)。然后执行关键终结器。
批评定格器具有罕见的用途,例如对于需要在任何情况下关闭的手柄。但您也可以使用它们来保持资源处于打开状态,直到执行所有终结器以启用例如tracing even inside finalizers