如何在Java中正确删除数组

2022-09-04 06:28:50

我在Java中已经4天了,从我搜索的教程中,教师们将大量精力集中在解释如何分配二维数组(例如)上:

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

...但我没有找到任何解释如何删除它们的东西。

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

话虽如此,我是否可以只引用第一个元素块,垃圾回收器就可以完成这项工作?

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

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

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


答案 1

解释

您不能在 Java 中显式删除某些内容。垃圾回收器的工作就是要做到这一点。它将删除任何人不再使用的任何内容。因此,要么

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

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


引用

要了解为什么重新分配外部数组就足以删除内部数组,您需要了解它们是如何被引用的。同样,垃圾回收器可以删除任何无法访问的内容。因此,让我们看一下数组,例如:

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

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

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

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

现在假设您将通过另一个变量引用其中一个内部数组:

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}

答案 2

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

如果要在变量超出范围之前清空引用(请记住,如果某些其他代码具有此引用,则不会对其进行垃圾回收):

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

...

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