C#在运行时编译finalize方法?

时间:2012-04-06 10:50:43

标签: c# .net .net-4.0 clr

在阅读有关GC的3本书时,我注意到一些奇怪的事实:

C#通过CLR

CriticalFinalizerObject CLR以非常特殊的方式处理此类及其派生的类

enter image description here

什么???

“没有找到足够的内存来编译一个方法?”恕我直言 - 代码应该已经编译了......不是吗?

当我编写c#代码时 - 整个代码在运行之前被编译为IL ...不是吗? 但根据文本 - 在 RUNTIME - 他可能找不到足够的内存用于编译 ......

帮助?

3 个答案:

答案 0 :(得分:5)

JIT编译器仅在第一次执行时在运行时编译从IL到本机代码的方法。正如您所料,这需要额外的内存。因此,正常的终结器只能在清理线程执行之前编译。

CriticalFinalizerObject派生的对象立即编译了终结器,因此在程序关闭时不需要额外的内存来执行它。这适用于必须执行终结器的对象(尽管有断电或类似情况)

答案 1 :(得分:2)

我认为它是'编译器'的后端。从IL到机器代码。

答案 2 :(得分:1)

使用编译器是JIT编译器,它意味着急切地编译终结器方法,而不是在执行之前不久延迟编译。

背后的深层原因是在执行所有正常终结器之后,在应用程序关闭期间调用这些终结器。但CLR确实执行所有挂起的终结器,超时时间为2秒(至少这是因为.NET 2.0从那以后没有检查过)。然后执行关键终结器。

批评定格器具有罕见的用途,例如对于需要在任何情况下关闭的手柄。但您也可以使用它们来保持资源处于打开状态,直到执行所有终结器以启用例如tracing even inside finalizers