这是msdn文章的摘录。文章可以找到here
有一个专门用于调用Finalize方法的特殊运行时线程。当可释放队列为空(通常是这种情况)时,该线程会休眠。但是当条目出现时,此线程会唤醒,从队列中删除每个条目,并调用每个对象的Finalize方法。因此,您不应该在Finalize方法中执行任何代码,该方法对正在执行代码的线程做出任何假设。例如,避免在Finalize方法中访问线程本地存储。
这是我之前提出过的一个问题,我因为同样的说法没有专门的线程来处理Finalizable对象,而且我的信息源是错误的。如果本文解释的是真的,我想知道为什么CLR需要一个特殊的线程来调用Finalize方法?
答案 0 :(得分:3)
没有关于什么终结器需要单独的线程,但请考虑这一点:
然而,一个看似合理的天真解决方案是做以下事情:
这可能很容易实现。 GC操作可以自由访问与堆相关的所有数据结构,并且可以随意执行任何操作,因为没有其他访问这些内容的线程正在运行。
但是,这会使程序暂时“长时间”暂停,并且在大多数应用程序中都是非常不可接受的。
因此,在GC上工作的团队选择了暂停最小可能时间的解决方案,仅在需要时暂停(第0代和第1代集合),同时在收集第2代时让应用程序继续运行。这更难。 注意,这是我的假设,我无法访问实际的设计文档或任何有关此信息的可靠信息。这些假设基于官方文档。
回到终结者线程。这些对象已经“死”并且已经计划好收集,所以代替上面的设计决定,为什么要打扰其中一个主线程做这个应用程序?由于GC已经在后台执行操作,因此以相同的方式处理死对象的最终确定似乎是一个很好的决定。
答案 1 :(得分:0)
考虑到所有这些观察结果,用于最终确定的专用线程看起来非常合理且有效。
答案 2 :(得分:0)
您可以通过利用并发性来提高性能,尤其是在具有多个CPU核心的现代处理器体系结构上。垃圾收集非常有用,但它可能会对性能产生一些影响,因为当垃圾收集器重新排列内存中对象的布局时,您的应用程序基本上无法执行任何操作。但是,任何最终化都可以在后台执行,这就是为什么它是在一个单独的线程上完成的,以提高性能。