为什么java.util.Arraylist#clear以OpenJDK的方式实现?

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

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)表现对我来说似乎不太好,或者我错过了什么?

按照它们的方式执行操作可让您重用arrays而无需重新分配其后备存储。 如果你想重新分配数组,你可以自己完成,因为ArrayList的表示主要由它的后备存储组成。

如果他们作为一个整体发布了数组,那么调用clear()和重新分配ArrayList本身之间几乎没有什么区别。 现在,他们为您提供了重新选择arrays或将其替换为全新arrays的选择。

此实现允许在不重新分配的情况下重用数组。 无论如何,在java中分配数组都可以是O(n),因为JVM会将所有元素初始化为默认值。

如果你清楚()一个ArrayList,你显然打算重用它 – 所以任何重用都可能在其中具有相同数量的对象。 因此,避免resize操作似乎是一个好主意。

另外,请记住,JIT编译在这里很重要 – 可能很多 – 该循环将非常缓存友好且各个操作非常便宜 – 在编译的情况下可能只是每个机器指令。

这与Java的LinkedList中的clear()impl是相同的原因,它是Java Generational Garbage Collection 。

这个ArrayList和后备数组更有可能被提升到“老一代”,在那里它可以保留更有可能在年轻代中的数组索引引用的对象。 将所有索引设置为null允许在收集后备arrays之前收集这些较年轻的对象。