Java的LinkedList中的clear()impl

时间:2009-02-22 22:46:10

标签: java linked-list clear

我担心这是一个非常愚蠢的问题,但这里有:

为什么Java的默认LinkedList实现中的clear方法是否需要遍历列表并取消挂钩所有节点?为什么不解开标题并将列表的其余部分保持连接 - GC无论如何都会得到它,不是吗?

以下是方法:

/**
 * Removes all of the elements from this list.
 */
public void clear() {
    Entry<E> e = header.next;
    while (e != header) {
        Entry<E> next = e.next;
        e.next = e.previous = null;
        e.element = null;
        e = next;
    }
    header.next = header.previous = header;
    size = 0;
modCount++;
}

为什么要走路?为什么不跳到header.next = header.previous = header;

我能想到的最好是它有助于GC ...?这个链接http://java.sun.com/docs/books/performance/1st_edition/html/JPAppGC.fm.html#997442表明了这一点。

... TIA

4 个答案:

答案 0 :(得分:18)

他们的方法确保即使其他代码仍保留对特定节点的引用,其他节点也将是GC。

否则,即使对其中一个节点的单个外部引用也会阻止整个链被收集。

此外,列表中的其他操作可能同时进行(例如,通过subList()Collections.unmodifiableList(),迭代器查看),这可以确保这些内容立即将列表视为“空”。 / p>

答案 1 :(得分:2)

IIRC,这是JDK6中的一项改进,以帮助某些(世代)GC算法的性能。通常,List本身和较旧的节点将处于比其他节点更老的一代中。年轻一代将被更频繁地收集,结果是在发现所有节点都是垃圾之前,年轻节点被复制了。

所以这是一个次要的性能优化。内存性能优化有点奇怪,因为通常不会导致问题的代码需要额外的时间来执行。

答案 2 :(得分:0)

我只是在我的游戏开发博客上推测这个问题。谢谢你的回答。我认为节点暴露是一个值得怀疑的设计余量。这也是粗略的,列表上的替代视图(迭代器等)将依赖于节点取消链接以快速失败。列表上的子视图应该检查修改计数,而不是依赖于这种副作用行为。无论如何,我明白为什么他们现在仍然坚持下去。

答案 3 :(得分:0)

http://developer.classpath.org/doc/java/util/LinkedList-source.html处的 java.util.LinkedList 的源代码表明您可以简单地将第一个和最后一个元素设置为null。

当然,如果你倾向于过度保护,你可以循环整个过程。我个人认为,如果您的列表包含数千个元素,这可能是一项非常昂贵的任务。

相关问题