ArrayList.clear()方法是否会释放内存?

26
如果我没记错的话,ArrayList 包含了您添加到列表中的变量所存储的内存位置的值。因此,我的假设是当您调用 ArrayList.clear() 方法时,它仅释放上述内存位置的值,而不释放这些内存位置本身。我将尝试通过一个示例来说明这一点:
假设您有当前的内存状态:
[Memory location] (type of variable) *value*

[1000] (int) 32

[1002] (int) 12

[1003] (float) 2.5

然后您将它们添加到列表 myList 中,因此它包含指向1000、1002、1003内存位置的指针。

当您调用 myList.clear() 时,指针将被置空,但内存位置1000、1002、1003仍将包含先前给定的值。我错了吗?


2
这篇文章 https://dev59.com/Emw15IYBdhLWcg3wMpEY 可以帮助你。 - Pankaj Kumar
2
请注意,ArrayList 永远不包含像 int 这样的原始类型,而是包含像 Integer 这样的对象。这对于答案来说非常重要。 - Sean Owen
4个回答

16
你说得对,因为内存是由垃圾回收器异步清除的,而不是直接由这些库函数清除。 clear仅会将它们全部置空,并相应地更新ArrayList状态。
如果其中任何一个或所有元素在您的代码的其他部分中未被引用,则它们变得有资格进行垃圾回收,并可能在该调用后的短时间内至永远被销毁和释放。

谢谢,我会确保手动处理被丢弃的变量 :) 干杯,头像很棒。 - nstosic
@NitroNbg,没有必要手动操作任何东西,只要它们没有被引用,它们就会被释放,谢谢 :) - Karthik T

6

clear 只会将后备数组元素置为 null

public void clear() {
    modCount++;
    for (int i = 0; i < size; i++)
        elementData[i] = null;
    size = 0;
}

但是如果我们在清空后调用ArrayList.trimToSize,支持数组将会收缩。

public void trimToSize() {
    modCount++;
    int oldCapacity = elementData.length;
    if (size < oldCapacity) {
        elementData = Arrays.copyOf(elementData, size);
    }
}

这样做,在问题的背景下,会浪费空间,不是吗?因为现在处于GC临界状态的不仅仅是已清除的元素,还有数组本身。 - Karthik T

6
不会的,它不会清除内存。在你使用clear()之后。

查看clear()的源代码。

 public void More ...clear() {
    modCount++;

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

该方法是使元素有资格被垃圾回收器处理,而不是立即清除它们。一旦垃圾回收运行,它们就会消失。

2
您的问题的答案是,这将不会“释放”内存。它只会删除所有“对象引用”。现在,这些对象可能会或可能不会被垃圾收集器收集,具体取决于它们在其他地方如何被引用。
例如,
Object 1 refers - > Object 2
ArrayList refers - > Object 2
ArrayList refers - > Object 3

在这种情况下,在执行Arraylist.clear()之后,对象3将有资格进行清理,但对象2不会。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接