【问题标题】:Garbage collection - orphaned LinkedList links垃圾收集 - 孤立的 LinkedList 链接
【发布时间】:2011-10-19 14:51:01
【问题描述】:

假设您有引用 A -> B -> C -> D。当您从A 中删除对B 的引用时,您将得到一个孤立的对象链B -> C -> D

CD 是否会被垃圾回收,即使无法找到它们(因为没有引用 B)?

我认为 GC 对此很聪明,并且会解决任何此类依赖关系。

但是,我查看了 source codeLinkedList 类,发现一些与此信念相反的东西。我注意到当列表为clear()ed 时,对每个链接的所有引用都明确设置为null,因此使其成为O(n) 操作。这样做有什么理由/好处吗?

【问题讨论】:

    标签: java garbage-collection linked-list


    【解决方案1】:

    是的,C 和 D 将被垃圾回收,假设 B 是唯一引用它们的东西。这是因为它们无法从图到应用程序对象图的根对象。

    我想在LinkedList 实现中标记每个链接到null 的原因是为了防止内存泄漏。 LinkedList 之外的东西可能会抓住头节点。如果发生这种情况,即使在 LinkedList 已被清除后,它仍会使所有其他节点保持活动状态。

    【讨论】:

    • 另外,nulling 它们可以让垃圾收集器更有效地清除它们,而无需遍历对象图,对吗?
    • 触发垃圾回收时,将遍历整个对象图并将对象标记为“正在使用”。所以,是的,我想它会使遍历更短。
    • 其实典型的垃圾回收器只会遍历可达对象图。不会遍历从 B 到 C 和 C 到 D 的链接,因此将它们归零对性能没有帮助。
    • @Stephen C:对不起,我不是很清楚。我在谈论可达对象图。我还假设将以前可访问的值归零将使遍历更短。我想我今天只是误解了大家......
    • 这是正确的,除非无法获得对头节点的外部引用,因为它是 private 并且没有获取器。
    【解决方案2】:

    看起来确实有点奇怪。也许它明确拆除列表的原因是为了清除现有迭代器和子列表以及父列表的列表。

    当然不是为了加快垃圾收集速度。垃圾收集器不会遍历无法访问的对象中的引用,因此将它们归零不会有任何区别。

    更新

    该方法的更新版本具有以下 cmets:

    // Clearing all of the links between nodes is "unnecessary", but:
    // - helps a generational GC if the discarded nodes inhabit
    //   more than one generation
    // - is sure to free memory even if there is a reachable Iterator
    

    因此,GC 似乎有好处,至少在某些情况下是这样。

    假设老一代中的Node 包含对年轻一代中对象(例如Node 或元素)的引用。该引用在收集年轻代时成为“根”,导致保留年轻代对象,即使老年代Node 不可达。这种状态一直持续到老一代被收集。老年代很少被收集。

    如果你遍历列表并拆解它,包含旧 -> 新引用的变量被分配一个null。该分配的写屏障导致(立即或在 GC 时)原始引用不再是“根”。因此,现在可以收集年轻代中的对象,并且它不会最终“永久”给老一代(这提前了需要收集该代的时间)。

    据推测,GC 的收益超过了取消选择列表的成本……无论是平均而言,还是在成本是灾难性的情况下。

    有关详细信息,请参阅 Jones 和 Lins 的“用于动态内存管理的垃圾收集算法”。它在我的(第一版)副本的第 7.5 章中。


    一般来说,最好将Collection 对象扔掉并重新开始,而不是清除它以供重用。

    【讨论】:

    • 啊,是的,这完全正确! Iterators 和ListIterators 都包含对内部节点的引用。 SubLists 但是不要。
    • 为了记录,源现在明确证明它可以使代代相传 GC 受益。
    • @shmosel 那什么可以让一代GC受益?
    • @KevinKrumwiede 我们在讨论什么……LinkedList 的解散。
    • @shmosel 明确地说,您是反对还是支持最好将整个列表扔掉的说法?我查看了 GrepCode 上的 LinkedList 源,但没有找到您所指的内容。 (我知道,这个帖子很老了……)
    猜你喜欢
    • 2020-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-20
    • 1970-01-01
    • 2011-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多