我担心这是一个非常愚蠢的问题,但这里有:
为什么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
答案 0 :(得分:18)
他们的方法确保即使其他代码仍保留对特定节点的引用,其他节点也将是GC。
否则,即使对其中一个节点的单个外部引用也会阻止整个链被收集。
此外,列表中的其他操作可能同时进行(例如,通过subList()
或Collections.unmodifiableList()
,迭代器查看),这可以确保这些内容立即将列表视为“空”。 / p>
答案 1 :(得分:2)
List
本身和较旧的节点将处于比其他节点更老的一代中。年轻一代将被更频繁地收集,结果是在发现所有节点都是垃圾之前,年轻节点被复制了。
所以这是一个次要的性能优化。内存性能优化有点奇怪,因为通常不会导致问题的代码需要额外的时间来执行。
答案 2 :(得分:0)
我只是在我的游戏开发博客上推测这个问题。谢谢你的回答。我认为节点暴露是一个值得怀疑的设计余量。这也是粗略的,列表上的替代视图(迭代器等)将依赖于节点取消链接以快速失败。列表上的子视图应该检查修改计数,而不是依赖于这种副作用行为。无论如何,我明白为什么他们现在仍然坚持下去。
答案 3 :(得分:0)
http://developer.classpath.org/doc/java/util/LinkedList-source.html处的 java.util.LinkedList 的源代码表明您可以简单地将第一个和最后一个元素设置为null。
当然,如果你倾向于过度保护,你可以循环整个过程。我个人认为,如果您的列表包含数千个元素,这可能是一项非常昂贵的任务。