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

为什么java.util.Arraylist#clear的实现方式与OpenJDK相同?,java,performance,openjdk,Java,Performance,Openjdk,public void clear(){ modCount++; //让gc完成它的工作 对于(int i=0;i

public void clear(){
modCount++;
//让gc完成它的工作
对于(int i=0;i
我的问题是,当他们本可以重新初始化备份数组时,为什么他们必须在备份数组{O(n)}中循环一次,使每个元素都符合垃圾收集的条件,丢弃对整个数组{O(1)}的引用,并使其符合垃圾收集的条件?
O(n)
clear()
的性能对我来说似乎不太好,还是我遗漏了什么?

按照他们的方式进行操作可以让您重用阵列,而无需重新分配其备份存储。如果您想重新分配阵列,您可以自己完成,因为
ArrayList
的表示主要由其备份存储组成


如果他们将数组作为一个整体释放,那么调用
clear()
和重新分配
ArrayList
本身之间的差别将非常小。现在,它们为您提供了一个选项,您可以选择是重用阵列,还是用全新的阵列替换阵列。

此实现允许阵列重用,而无需重新分配。因为JVM会将所有元素初始化为默认值。

如果你清除了一个ArrayList,你显然打算重用它——因此任何重用都可能有相同数量的对象。因此,避免调整大小操作似乎是个好主意

另外,请记住JIT编译在这里很重要,可能会有很多—循环将是非常友好的缓存—单个操作非常便宜—在编译的情况下,每个操作可能只有一条机器指令

这与Java的原因相同


此ArrayList和支持数组更有可能升级到“老一代”,在“老一代”中,它可以保留由数组索引引用的对象,这些对象更有可能位于年轻一代。将所有索引设置为null可以在收集备份数组之前收集这些较年轻的对象。

可能的重复我不认为这是重复的。几乎相同的方法,可以执行类似的操作:
for(loop\u to\u list as e){e=null}
//pseudocode@SayoOladeji正确的,但这需要一个循环,并且每次将元素设置为
null
时都需要额外的参数检查。当你做
new ArrayList()
的时候,你用一行换一行,而不是用一行换一个循环。现在我对天真的
def arr=new Object[n]
有了完全不同的看法,谢谢!琐事:在java中分配新数组时,java会通过将每个值设置为
null
或0来自动确保其中没有“垃圾”,除非JIT能够在读取之前检测到整个数组被写入。手动将所有值设置为null将比创建相同大小的新数组提供更高的性能。
public void clear() {
    modCount++;

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

    size = 0;
}