2009-02-22 48 views
11

明确()IMPL我担心这是一个非常愚蠢的问题,但在这里有云:在Java中的LinkedList的

为什么在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 ...

回答

18

他们的方法可以确保即使其他代码仍持有到特定节点的引用,其他节点将GC'ed。

否则,即使对其中一个节点的单个外部引用也会阻止整个链的收集。另外,列表中的其他操作可能正在同时进行(例如,通过subList()Collections.unmodifiableList()迭代器的视图),并且这确保了这些事物立即将列表视为“空”。

+0

我都不同意,说外部代码无法获得对LinkedList $ Entry的引用......但是通过LinkedList $ ListItr间接你肯定可以......非常感谢! – overthink 2009-02-22 23:14:33

2

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

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

0

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