为什么不是LinkedList.Clear()O(1)

时间:2011-03-01 22:12:03

标签: java big-o

我假设LinkedList.Clear()在我正在处理的项目上是O(1),因为我使用LinkedList来消耗我需要高吞吐量的BlockingQueue,然后清除并重用LinkedList。 / p>

事实证明这种假设是错误的,因为(OpenJDK)代码执行此操作:

    Entry<E> e = header.next;
    while (e != header) {
        Entry<E> next = e.next;
        e.next = e.previous = null;
        e.element = null;
        e = next;
    }

这有点令人惊讶,有没有什么好的理由,LinkedList.Clear不能简单地“忘记”它的header.next和header.previous成员?

3 个答案:

答案 0 :(得分:31)

我在Eclipse中看到的版本(build 1.7.0-ea-b84)中的源代码上面有这个注释:

// 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

这清楚地说明了为什么他们这样做,虽然我同意将O(1)操作转换为O(n)有点令人担忧。

答案 1 :(得分:3)

虽然我对GC优化的原因并不十分印象深刻 - 它显然适用于您的情况 -

  

清除并重复使用LinkedList

听起来不对劲。为什么不只是创建一个全新的LinkedList对象?

答案 2 :(得分:0)

因为我似乎无法评论答案(?):next和previous之间的指针无关紧要。由于任何GC根都无法访问任何内部条目,因此将收集整个结构。如果java使用了引用计数收集器,我们就会遇到循环问题。

John Skeet指出正确的答案。