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

下列五种事件会启动垃圾收集,收集结束时会调用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在未来可能会在将来改变它们)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值