如何在Java中正确删除数组

时间:2019-04-08 07:07:23

标签: java arrays

我使用Java已有4天的年龄,从我搜索的教程中,讲师将大量精力投入到如何解释如何分配二维数组(例如)上:

Foo[][] fooArray = new Foo[2][3];

...但是我没有找到任何说明如何删除它们的东西。

从内存的角度来看,变量fooArray将指向堆中的一块内存,其中有2个元素。每个元素也指向堆中的另一个块,该块具有3个元素。

话虽这么说,我可以只引用第一个元素块,然后垃圾收集器完成这项工作吗?

Foo[1] = null;Foo[2] = null;

还是我必须使每个实例化的Foo元素为空?

Foo[1][1] = null; Foo[1][2] = null; Foo[1][3] = null; ...

3 个答案:

答案 0 :(得分:16)

说明

您不能在Java中显式删除某些内容。这样做是垃圾收集者的工作。它将删除任何人不再使用的任何内容。所以

  1. 让变量超出范围或
  2. 分配null
  3. 或其他任何实例。

然后不再引用该数组实例(及其子数组),垃圾回收器最终将其删除。


参考

要了解为什么重新分配外部数组足以删除内部数组,您需要了解如何引用它们。同样,垃圾收集器可以删除 unreachable 的所有内容。因此,让我们看一下这样的数组:

int[][] outer = {{1, 2}, {3, 4}, {5, 6}};

我们有4个数组实例。一种是int[][]类型,而三种是int[]类型。另外,我们有一个变量outer。实例引用如下:

                       ___> {1, 2}
                      |
outer  --> int[][] ---|---> {3, 4}
                      |
                      |___> {5, 6}

因此,通过删除outer,再也没有人引用int[][]。垃圾收集器现在可以将其删除。但这也会删除对内部数组的所有引用,因此垃圾收集器现在也可以删除它们。

现在假定您将通过另一个变量引用内部数组之一:

int[][] outer = {{1, 2}, {3, 4}, {5, 6}};
int[] thirdInner = outer[2];
other = null; // remove the reference

现在的情况

outer  --> null

                       ___> {1, 2}
                      |
           int[][] ---|---> {3, 4}
                      |
                      |______> {5, 6}
                          |
thirdInner _______________|

因此,垃圾收集器现在将删除外部数组int[][],这还将删除对第一个和第二个内部数组的所有引用。但是第三个仍然被thirdInner引用,因此在垃圾回收之后,我们有:

outer       --> null
thirdInner  --> {5, 6}

答案 1 :(得分:13)

在数组超出范围后的某个时刻,如果没有其他引用,则垃圾收集器将回收内存。

如果您想在变量超出范围之前使引用为空(请记住,如果其他代码具有此引用,则不会垃圾回收):

Foo[][] fooArray = new Foo[2][3];

...

// this will null the reference to the array
fooArray = null;

答案 2 :(得分:2)

与C不同,Java提供了自动垃圾收集功能,它将在无法访问(即超出范围)时为您清除数组。如果您希望将数组设置为null,以使内存位置无法访问。 / p>

    Foo[][] fooArray = new Foo[2][3];
    .
    .
    .
    fooArray = null;
    System.gc();

此gc调用不能确保JVM将运行垃圾回收器,但是它建议Java虚拟机将精力花在回收未使用的对象上,以使它们当前占用的内存可用于快速重用。当控件从方法调用返回时,Java虚拟机将尽最大努力从所有丢弃的对象中回收空间