2012-04-06 82 views
0

由于IM通过关于GC 3本书,我已经通知了一些奇怪的事实阅读:通过CLRC#编译finalize方法的运行时?

C#

CriticalFinalizerObject的CLR对待这个类和类从它在一个非常特殊的方式衍生

enter image description here

什么???

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

当我编写C#代码 - 整个代码编译为IL之前,其运行...不? 但根据文本 - 在RUNTIME - 他可能会发现内存不足编译 ...

帮助?

+0

这完全可以解释为什么敲定,则不能保证被执行,所以不要轻易恐慌:) – 2012-04-06 11:13:50

回答

5

JIT编译器仅在运行时第一次执行时将IL中的方法编译为本地代码。正如你所期望的那样,这需要额外的内存。因此,正常的终结器只在被清理线程阻止之前才被编译。

CriticalFinalizerObject派生的对象将立即编译终结器,因此在程序关闭时不需要额外的内存来执行它。这对于必须有其终结执行,如果在所有可能的对象(nonwithstanding停电或类似)

+0

在什么情况下必须必须运行finilizer? Finilizers用于非托管资源,当操作系统恢复其控制权时,它将(最终)被回收... – 2012-04-06 11:31:55

+1

在进程关闭期间,没有理由。这在使用许多AppDomain并且不时像Web服务器一样卸载的环境中很有意义。这有助于在服务器进程中存活时间更长,当且仅当应用程序域由于未处理的扩展而不是未扩展时。 – 2012-04-06 11:35:27

+0

@AloisKraus'有助于延长服务器进程'我看不到整个图片。抱歉。可以说我有A,B,C,D应用程序域。 'CriticalFinalizerObject'在这里可以帮到我什么(运行'CriticalFinalizerObject')我需要一个真实的生活示例,所以我可以理解而不是书本定义。你能回答吗? – 2012-04-06 11:40:20

2

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

+0

你应该说JIT编译器更具体。 – 2012-04-06 11:12:37

1

使用编译器是JIT编译器,意在尽快编译您的终结器方法,并且不会在执行之前不久延迟其编译。

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

临时终结器有罕见的用途,例如,对于任何情况下需要关闭的手柄。但是您也可以使用它们来保持资源开放,直到执行完所有终结器以启用tracing even inside finalizers