当我们创建一个数组的数组时,有多少个对象可以被垃圾收集器处理?

3
public class GarbageCollectionTest{

    public static void main(String...args){
        int [][]a = new int[4][3];//line 1
        a[0] = new int[2];// line 2
        a[2] = new int[3];// line 3
        a = new int[3][2];  //line 4
    }
}

我有点困惑,在第三行后还有多少个对象可以被垃圾回收器清除。我查找了相关解决方案,但是对我找到的答案并不满意。


1
执行完第四行后,您是指这个意思吗? - SamB
好的,你重新分配了两个对象,因此我假设你有两个对象(两个数组)可供垃圾回收。 - markspace
1
你想了解垃圾回收方面的具体内容吗?一般来说,垃圾回收会自动“做正确的事情”,清理掉你无法再引用的对象。 - dimo414
2个回答

2

好的,让我们逐行浏览它:

您创建一个新的 int 2D 数组 a:

int [][]a = new int[4][3];//line 1

你需要在数组a中替换两个数组:

a[0] = new int[2];// line 2
a[2] = new int[3];// line 3

您可以重新分配变量a并创建一个新数组:

a = new int[3][2];  //line 4

在第三行之后,您替换的两个数组将被选中。

在第四行之后,垃圾回收器将回收放置在“旧”a中的每个对象(数组),因此总共有4个对象(int不是对象,请参见Konstantins答案这里)。

4 + 2 +对“旧”a本身的引用=总共7个

希望我理解得正确 ;)


1
垃圾收集发生在程序不再引用对象时,而不是创建对象时,因此,“当我们创建一个数组的数组”时,就垃圾收集方面没有任何影响。一个基本类型的二维数组,例如 int[][],由一个对象数组组成,其中包含对 n 个 int[] 数组的引用(其中 n 是外部数组的大小 - 在您示例的第一行中为 4)。当您将该二维数组分配给 a 时,您从 a 到外部数组以及内部基元数组创建了引用,因此垃圾回收器不会删除任何这些对象。在第二行,您构造一个新的 int[],然后将其分配给外部数组的第一个索引。这个分配(而不是数组的创建)导致先前分配给索引 0 的 int[] 变得有资格进行垃圾收集,因为不再有任何引用它 - 它是“垃圾”。

第三行与之前相同,你构建一个新的int[],然后将其分配给一个索引,删除了先前引用的数组的唯一引用。现在它也可以被收集。因此,在第三行之后,有两个可以被收集的int[]对象。

第四行构建一个新的int[][],执行与上述相同的操作(一个对象数组持有nint[]数组),然后将该数组分配给a,从而删除对先前二维数组的唯一引用。此时,GC可以看到没有任何东西引用旧数组并清理它。一旦发生这种情况,内部数组也没有剩余引用,GC也可以清理它们。

在第四行之后,您仍然可以通过a引用这个新数组,以及它包含的数组。您之前构建的数组不再可达,因此最终将被GC清理掉。一旦GC有机会运行,内存中只剩下由a引用和它所引用的内部数组的数组。


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