1

如果假设一个对象实现了 Finalize 方法,但它内部引用了应用程序的一个活动的静态对象(糟糕的设计!但很有可能)。

现在,当 GC 启动并通过将对象放入终结队列中来终结对象,然后将其移动到 FReachable 队列中,它将调用其 finalize 方法。

但是哇!它发现它引用了一个活动对象,因此它不允许 GC 回收该对象占用的内存并再次标记该对象为活动对象。僵尸对象!

此时这个对象驻留在哪里?

  1. 仍然处于脆弱状态?
  2. 留在完成队列中?
  3. 以不确定的状态保留在托管堆上(从易碎队列和终结队列中删除)?

另外,对于此类对象, ReRegisterForFinalize() 的最佳位置是什么?

4

1 回答 1

1

它发现它指的是一个活着的对象

不要紧。传出引用与 GC 无关。

另一种情况是,通过将自己注册到某个根列表中,最终确定对象使自己再次可访问。

这称为复活。它不需要 GC 过多的特别注意:处理终结器并从 fReachable 中删除引用。请注意,没有什么特别的,fReachable 中的对象在任何时候都不会处于不确定状态。它们必须在下一次 GC 收集中重新扫描。终结器的成本之一是需要 2 轮 GC。

通常该对象会ReRegisterForFinalize(this)在它复活时调用。
但请注意,复活远非普遍做法。

于 2011-07-09T11:43:39.853 回答