Jam*_*ing 12 c# garbage-collection finalizer
在回答关于SO的另一个问题*以及随后的评论讨论时,我遇到了一个我不清楚的问题.
在我误入歧途的任何地方纠正我......
当垃圾收集器收集一个对象时,它会在一个单独的线程上调用该对象的终结器(除非终结器已经被抑制,例如通过一个Dispose()方法).在收集时,GC会挂起除触发集合的线程(除了背景集合)之外的所有线程.
不清楚的是:
*链接到原始问题:
.NET GC从终结器访问同步对象
Eri*_*ert 48
在收集垃圾收集器之前,垃圾收集器是否等待终结器在该对象上执行?
你的问题有点含糊不清.
当GC遇到需要完成的"死"对象时,它放弃了回收死对象存储的尝试.相反,它将对象放在"我知道需要完成的对象"的队列中,并将该对象视为活动,直到终结器线程完成它为止.
所以,是的,GC确实"等待",直到在回收存储之前执行终结器.但它不会同步等待.听起来你问"GC是否同步调用终结器?" 不,它将对象排队等待稍后完成并继续卡车运行.GC希望快速完成释放垃圾和压缩内存的任务,以便程序能够尽快恢复运行.在清理之前,它不会停止处理一些需要注意的怪物.它将该对象放在队列中并说"保持安静,终结器线程将在稍后处理你".
稍后GC会再次检查对象并说"你还在死吗?你的终结器会运行吗?" 如果答案是"是",那么对象将被回收.(请记住,终结器可能会使一个死对象重新变为现实对象;尽量不要这样做.结果没有任何令人愉快的事情发生.)
在终结器仍在执行时是否取消挂起线程?
我相信GC解冻了它冻结的线程,并向终结器线程发出信号"嘿,你有工作要做".因此,当终结器线程开始运行时,GC冻结的线程将再次启动.
可能必须存在未冻结的线程,因为终结器可能需要将调用编组到用户线程以释放线程关联资源.当然,其中一些用户线程可能被阻止或冻结; 线程总是被某些东西阻挡.
如果终结器遇到其中一个被挂起的线程持有的锁,会发生什么?终结器线程是否会死锁?
完全正确.终结器线程没有任何魔力可以阻止它死锁.如果用户线程正在等待终结器线程取出的锁定,并且终结器线程正在等待用户线程取出的锁定,那么您就会遇到死锁.
终结器线程死锁的例子比比皆是.这是一篇关于其中一个场景的好文章,其中包含一系列指向其他场景的链接:
正如文章所述:终结器是一种极其复杂和危险的清理机制,如果可能的话你应该避免它们.让终结器出错是非常容易的,并且非常难以正确使用.
| 归档时间: |
|
| 查看次数: |
7600 次 |
| 最近记录: |