2010-03-25 179 views
15

如果應用程序崩潰,析構函數會被調用嗎?如果這是一個未處理的異常,我猜測它確實存在,但更嚴重的錯誤或類似於用戶殺死應用程序過程的東西呢?析構函數 - 如果應用程序崩潰,它會被調用

,還有一些人可能愚蠢的問題:

  • 會發生什麼情況都在一個應用程序的應用程序退出,所有的終結已經被執行時的對象 - 做對象被垃圾收集或者是它們在某種程度上都「卸載「進程或appdomain?
  • 是每個應用程序的垃圾收集器部分(在相同的進程中運行)還是獨立的?
+1

什麼樣的崩潰?異常不是崩潰,而是可恢復的錯誤。 – Dykam 2010-03-25 10:33:54

回答

21

我鼓勵你爲自己嘗試一下。例如:

using System; 

class Program { 
    static void Main(string[] args) { 
    var t = new Test(); 
    throw new Exception("kaboom"); 
    } 
} 
class Test { 
    ~Test() { Console.WriteLine("finalizer called"); } 
} 

在命令提示符下運行此命令,以便您可以看到最後一個喘息。首先用throw語句註釋掉。

與Windows中的任何未處理的異常一樣,Windows提供的默認異常過濾器調用WerFault.exe顯示的Windows錯誤報告對話框。如果你點擊「關閉程序」,WerFault將使用TerminateProcess()來終止程序。這是一個快速結束,沒有機會運行終結器線程,就像程序正常退出時會發生的那樣。

然後Windows會照顧清理彈片。它會自動關閉您的程序可能已經打開但沒有機會在終結器中關閉的任何操作系統句柄。文件是棘手的問題,它們的緩衝區不會被刷新,你會很容易地在磁盤上寫入一個部分寫入的文件。

+1

+1。 Thx,非常豐富。我肯定會給出這個和其他一些想法,試圖看看發生了什麼。 – anakic 2010-03-25 13:23:58

4

我甚至不知道C#,但基於我對其他編程語言的經驗,我猜測:如果一個應用程序崩潰,那意味着它有一些嚴重錯誤。不正確的內存處理等。在這種情況下,任何編程語言嘗試執行析構函數/釋放器/終結器/ ...都會很奇怪。事情很可能只是去更不對;)

更新:(忘了嘗試回答您的其他問題)再次,不C#特異的,但通常沒有保證析構函數/ deallocators /終結/ ...實際上被叫了。原因在於,當一個進程退出時,簡單地「刪除」用於進程的內存塊比運行其析構器等來清理內存要容易和高效。

我不知道如何回答你的最後一個問題,而不會涉及太多的技術細節。有幾種垃圾收集器可以設計和運行的方式,最簡單的是垃圾回收停止當前進程並在完成時繼續執行,儘管垃圾收集器同時運行也是可能的(但更困難)與他們正在收集內存的進程。

您可能想閱讀垃圾收集理論以更好地理解所有這些。實際上有一個關於這個話題的整個網站:www.memorymanagement.org

+0

Thx,很好的答案。但有一件事看起來不正確 - 你說即使應用程序正常退出,某些析構函數仍然可能不會被調用......對我來說這看起來並不正確,因爲垃圾回收器或任何人都沒有辦法否則(但是對象本身)知道應用程序的管理對象可能使用了哪種本地資源,所以它無法處理它。無論如何,我會嘗試一下,因爲nobugs已經消失,並且在我得到一點時間後發佈結果... – anakic 2010-03-25 13:15:23

+0

我不能說C#,但Objective-C在這裏提供了一個有趣的示例。您應該比較'dealloc'(這是GC關閉時的析構函數)和'finalize'(當GC打開時)的文檔。對於'dealloc',文檔非常明確地說,不能保證它會被調用,你不應該依賴它來例如關閉文件。對於'finalize',文檔更模糊,似乎表明你可以依靠'finalize'作爲'備份'來確保文件被關閉等,但是我找不到明確說'finalize'的句子是保證被叫。 – Rinzwind 2010-03-25 14:21:28

+0

下面是Objective-C中'dealloc'和'finalize'文檔的鏈接。順便說一句:雖然只是嘗試一個實驗,看看它們是否用C#調用是好的,但你也應該看看文檔。如果您的實驗顯示它被調用,但文檔沒有說有*保證*,那麼在未來版本或其他平臺上可能會更改,所以您最好不要依賴它。 Obj-C文檔。鏈接:http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/dealloc – Rinzwind 2010-03-25 14:22:58

3

如果殺死一個應用程序,應用程序幾乎100%會立即失去控制權,並且沒有機會調用析構函數。

相關問題