2012-04-06 79 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