关闭

CLR Via C#读书笔记——Finalize方法被调用的时机【2011-01-18】

537人阅读 评论(0) 收藏 举报

下列五种事件会启动垃圾收集,收集结束时会调用Finalize方法:

 

1.第0代对象充满:第0代对象充满时开始执行垃圾收集。该事件是目前导致Finalize方法被调用的最常见的一种方式,因为事件通常在应用程序代码运行过程中分配新对象的时候发生。

 

2.代码显示地调用System.GC的静态方法Collect:代码可以显式地请求CLR执行垃圾收集。虽然Microsoft强烈建议不要这样做,但某些时候强制执行垃圾收集对应用程序来说还是有意义的。

 

3.Windows报告内存不足:CLR内部使用了Win32的CreateMemoryResourceNotification和QueryMemoryResourceNotification函数来监视系统的整体内存。如果Windows报告内存不足,CLR将强制执行垃圾收集,尝试释放死亡对象以减小进程工作集的大小

 

4.CLR卸载应用程序域:当一个应用程序域被卸载时,CLR会认为该应用程序域中不存在任何根,因此会对应用程序域中所有代的对象执行垃圾收集。

 

5.CLR被关闭:当一个进程正常终止时(与外部关闭相反,例如,通过任务管理器关闭),CLR就会关闭。在关闭过程中,CLR会认为该进程中不存在任何根,因此会调用托管堆中所有对象上的Finalize方法。注意,此处CLR不准备压缩或者释放内存,因为整个进程正在被终止,Windows将回收进程的所有内存。

 

 

CLR使用一个特殊的专用线程来调用Finalize方法。对于前面列出的前4种事件来说,如果有Finalize方法进入了一个无限循环,那么这个特殊的线程将被阻塞,其他的Finalize方法将得不到调用。这种情况非常糟糕,因为应用程序将不能够再回收其他终结对象占用的内存——只要应用程序还在运行,它就存在泄漏内存的可能。

 

对第5种事件来说,每个Finalize方法会有大约2秒钟的运行时间。如果一个Finalize方法没有在2秒钟内返回,那么CLR将中断该进程——其他的Finalize方法将得不到调用。另外,如果调用所有对象的Finalize方法超过了40秒钟,那么CLR也会中断该进程。(这些为超时设定的值Microsoft在未来可能会在将来改变它们)

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:127973次
    • 积分:1889
    • 等级:
    • 排名:千里之外
    • 原创:67篇
    • 转载:11篇
    • 译文:0篇
    • 评论:11条
    文章分类
    最新评论