GarbageCollectionandFinalizers:BetterPointsclearquestion。无论我误入歧途,请纠正我...当垃圾收集器收集对象时,它会在单独的线程上调用对象的终结器(除非终结器已被抑制,例如通过Dispose()方法)。在收集时,GC会挂起除触发收集的线程之外的所有线程(后台收集除外)。不清楚的是:垃圾收集器是否在收集对象之前等待终结器在该对象上执行?如果不是,它是否会在终结器仍在执行时取消挂起线程?如果它确实等待,如果终结器遇到一个挂起线程持有的锁,会发生什么?终结器线程会死锁吗?(在我的回答中,我认为这是一个糟糕的设计,但我可能会看到可能发生这种情况的情况)*原始问题的链接:.NETGC在垃圾收集器收集之前从终结器访问同步对象,垃圾收集器是否等待终结器在那个对象上执行?你的问题有点含糊。当GC遇到需要终结的“死”对象时,它会放弃尝试回收死对象的存储。相反,它将对象放在“我知道需要终结的对象”队列中,并将该对象视为活动对象,直到终结器线程完成它。所以,是的,GC会“等待”直到终结器在回收存储之前执行。但它不会同步等待。听起来你在问“GC是否同步调用终结器?”不,它将对象排队等待稍后完成并继续运送。GC希望快速完成释放垃圾和压缩内存的任务,使程序尽快恢复运行。它不会停止处理一些需要注意的小怪,直到它被清理干净。它将那个对象放在队列中并说“保持安静,终结器线程稍后会处理你”。之后GC将再次检查该对象并说“你还死了吗?还有你的终结器吗?”如果答案为“是”,则该对象将被回收。(请记住,终结器可能会将死对象重新创建为真实对象;尽量不要这样做。结果不会有任何令人愉快的事情发生。)在终结器仍在执行时取消挂起线程吗?我相信GC会解冻它冻结的线程,并向终结器线程发出“嘿,你有工作要做”的信号。因此,当终结器线程开始运行时,GC-frozen线程再次启动。可能必须有一个未冻结的线程,因为终结器可能需要编组对用户线程的调用以释放与线程相关的资源。当然,其中一些用户线程可能会被阻塞或冻结;线程总是被某些东西阻塞。如果终结器遇到挂起线程之一持有的锁,会发生什么情况?终结器线程会死锁吗?完全正确。终结器线程没有什么神奇之处可以防止它死锁。如果用户线程正在等待终结器线程获取的锁,而终结器线程正在等待用户线程获取的锁,那么就会发生死锁。终结器线程死锁的例子比比皆是。这是一篇关于其中一个场景的好文章,以及一系列指向其他场景的链接:http://blogs.microsoft.co.il/blogs/sasha/archive/2010/06/30/sta-objects-and-the-finalizer-thread-tale-of-a-deadlock.aspx如文章所述:终结器是一种极其复杂且危险的清理机制,您应该尽可能避免使用它们。终结器很容易出错,而正确则很难。包含终结器的对象往往寿命更长。在收集期间,当GC将终结器标记为垃圾时,它不会收集该对象(目前)。GC会将对象添加到将在GC完成后运行的终结器队列中。这样做的结果是,由于对象未被收集,它移至下一代(以及它引用的所有对象)。GC暂停所有正在运行的线程。另一方面,终结器线程将在应用程序继续运行时在后台运行。终结器调用所有注册为终结的对象的所有终结方法。在对象的终结器方法运行后,该对象将从队列中删除,并且从那时起该对象(可能还有它仍然引用的所有对象)都是垃圾。清除此对象会产生下一个对象集合,这些对象将(最终)删除该对象。由于第2代生成的对象的收集速度比第1代生成的对象快10倍,而第1代的收集速度比第0代快10倍,因此最终的垃圾收集可能需要一些时间。因为终结器线程只是一个运行托管代码(调用终结器)的简单线程,所以它可能会阻塞甚至死锁。所以在finalize方法中尽可能少做是很重要的。因为终结器是后台线程,失败的终结器甚至会导致整个AppDomain崩溃(哎呀!)。你可以说这个设计很不幸,但如果你仔细想想,很难想象其他设计框架能有效地清理我们的烂摊子。所以,回答你的问题:是的,对象只有从终结器队列中移除后才是垃圾,GC才会收集它。GC暂停所有线程,甚至是终结器队列。终结器队列可能会死锁。在finalize方法中尽可能少加锁。最容易将垃圾收集器视为将对象分为四组:任何有根对象都无法访问的对象;从可实现的可终结对象列表中可以访问的对象,但不能从任何其他根对象访问的对象;这些在可实现的可终结对象列表中,但也可以通过该列表之外的某些根对象访问。那些不在可实现的可终结对象列表中,但可以通过该列表以外的某些根对象访问的对象。当垃圾收集器运行时,#1类型的对象会消失。#2的对象被添加到需要尽快终结的对象列表中,并从“实时可终结对象”列表中删除(从而成为类别#4的对象)。请注意,需要终结的对象列表是普通的根引用,因此当无法收集列表中的对象时,如果终结器完成时没有创建其他根引用,则该对象将移至类别#1。以上就是C#学习教程的全部内容:Garbagecollectionandfinalizer:一个更好的分享点。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场,如涉及侵权,请点击右边联系管理员删除。如需转载请注明出处:
