代码之家  ›  专栏  ›  技术社区  ›  overthink

JavaLink列表中的IMPL

  •  11
  • overthink  · 技术社区  · 17 年前

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

    为什么Java的默认链接列表实现中的清除方法麻烦地要遍历列表并解开所有节点?为什么不直接解开头并让列表的其余部分保持连接——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 有点像这样。

    蒂亚…

    4 回复  |  直到 12 年前
        1
  •  18
  •   Jason Cohen    17 年前

    他们的方法确保即使其他代码仍然保留对特定节点的引用,其他节点也将被gc'ed。

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

    此外,列表中的其他操作可能同时进行(例如,视图到 subList() Collections.unmodifiableList() ,迭代器),这可以确保这些东西立即将列表视为“空”。

        2
  •  2
  •   Tom Hawtin - tackline    17 年前

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

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

        3
  •  0
  •   nem    17 年前

    我只是在我的游戏开发博客上推测这个问题。谢谢你的回答。我认为节点暴露是一个值得怀疑的设计允许。列表上的其他视图(迭代器等)也依赖于节点取消链接以快速失败。列表中的子视图应该检查修改计数,而不是依赖于这种副作用行为。不管怎样,我知道他们为什么现在还坚持着。

        4
  •  0
  •   asiby    12 年前

    的源代码 java.util.linkedlist链接列表 http://developer.classpath.org/doc/java/util/LinkedList-source.html 建议您只需将第一个和最后一个元素设置为空。

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