【问题标题】:What happens to FReachable Objects if they are found to be reachable?如果发现 FReachable 对象是可访问的,会发生什么情况?
【发布时间】:2011-07-09 11:40:41
【问题描述】:

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

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

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

此时此对象驻留在何处?

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

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

【问题讨论】:

    标签: .net garbage-collection finalization


    【解决方案1】:

    它发现它引用了一个活着的对象

    没关系。传出引用与 GC 无关。

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

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

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

    【讨论】:

    • 您好,谢谢您的回答。所以您是说它已从终结和可访问队列中删除但仍保留在托管堆上?
    • 是的。它在终结器期间保留在堆上,并且仅在下一个 GC.Collect() 中被删除。如果仍然无法访问。
    • 嗨 Henk,看看这让我感到困惑。你说它在终结器期间仍然在堆上....但我问它在终结器之后停留在哪里?
    • 在终结器之后它仍然在堆上...等待下一次 GC。唯一的区别是它不再在终结器队列中,所以下次它会作为普通对象被收集。
    猜你喜欢
    • 2015-03-09
    • 2021-07-14
    • 2011-03-01
    • 1970-01-01
    • 2020-09-04
    • 2012-12-19
    • 2021-04-20
    • 1970-01-01
    • 2011-06-02
    相关资源
    最近更新 更多