@Jason:对于f-reachable队列是如此。但恕我直言,它并没有解释为什么有自己的定稿队列。
我的猜测是,终结队列有加另一个信息,帮助GC 所有对象的生命周期的可能状态之间进行区分。
对象头部中的终结标志表示“对象需要终结”或“对象不需要终结”,但并不表示终止是否已经发生。
但说实话,我不明白为什么它需要在当前的定稿过程实施。
事实上,这里是天真的流程我想可能没有终结队列:
- 创建对象时,如果它有一个终结,则GC设置结束标志;
- 如果后来SupressFinalize被调用,那么该标志被归零;
- 现在让我们跳到GC收集对象的方式,该对象从任何地方都没有被引用:如果设置了终结标记,则GC将该对象的引用放入f-reachable队列,并让终结线程运行;
- 后来终结线程退出引用,重置终结标志并运行终结器;
- 如果对象想要重新设定以后它可以ReRegisterForFinalize重新设置终止标志;
- 后来GC再次收集对象:如果没有设置终结标志,它知道没有什么要做,然后释放对象内存;
- 如果设置了终结标志,则GC再次将该对象的引用排入f可到达的队列,然后再次进入另一轮;
- 在某个时间点对象很高兴,完成定稿并收集;或者应用程序域或进程被关闭并且无论如何都释放内存。
因此,似乎在这些情况下不需要定型队列,只有定型标志是有用的。
一个可能的原因是,从概念的角度来看,可能会有一条规则:“一个对象被收集,当且仅当它没有被任何根引用”。 因此,没有确定队列,并且根据对象状态本身收集对象的决定,检查确定标志,与此规则不兼容。
但是我真的不认为GC的实现是基于这种理论规则的教条性应用,而只是基于实用的选择;所以很明显,我错过了一些关键场景,其中GC需要确定队列才能知道在收集对象时要做什么,但是哪些是?
哪个实现? – R0MANARMY 2011-04-11 23:45:30
垃圾回收.. – paseena 2011-04-11 23:46:30
我认为@ R0MANARMY表示哪个GC实现。 Universe中有多个.NET框架的实现。无论如何,哪个实现应该没有关系,因为问题是关于为什么* GC实现会实现终结器队列。 – 2011-04-11 23:49:08