关于性能:为什么 java.util.Arraylist#clear 以 OpenJDK 中的方式实现?

Why Was java.util.Arraylist#clear implemented the way it was in OpenJDK?

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/ArrayList.java#473

1
2
3
4
5
6
7
8
9
public void clear() {
    modCount++;

    // Let gc do its work
    for (int i = 0; i < size; i++)
        elementData[i] = null;

    size = 0;
}

我的问题是,为什么他们必须在支持数组 { O(n) } 中循环以使每个元素都符合垃圾回收条件,而他们本来可以重新初始化支持数组,将整个数组的引用丢弃为整个 { O(1) } 并使其有资格进行垃圾收集?
clear() 的 O(n) 性能对我来说似乎不太好还是我错过了什么?


按照他们的做法,您可以重复使用阵列,而无需重新分配其后备存储。如果您想重新分配数组,您可以自己完成,因为 ArrayList 的表示主要由它的后备存储组成。

如果他们将数组作为一个整体释放,那么调用 clear() 和重新分配 ArrayList 本身就没有什么区别了。现在,它们为您提供了一个选项,您可以在重复使用阵列或用全新的阵列替换它之间进行选择。


此实现允许数组重用而无需重新分配。无论如何,在 java 中分配一个数组可能是 O(n),因为 JVM 会将所有元素初始化为默认值。


如果您清除()一个 ArrayList,那么您显然打算重用它 - 因此任何重用都可能包含相同数量的对象。所以避免调整大小操作似乎是个好主意。

另外,请记住 JIT 编译在这里很重要,可能很多 - 该循环将非常适合缓存


n