2010-03-25 177 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%会立即失去控制权,并且没有机会调用析构函数。

相关问题