创建数组数组时,有多少对象符合垃圾收集器的条件?

时间:2016-07-23 16:25:05

标签: java garbage-collection

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
    }
}

我有点混淆,在第3行之后有多少对象符合垃圾收集器的条件。我已经搜索了解决方案,但我对找到的答案并不满意。

2 个答案:

答案 0 :(得分:2)

好的,让我们逐行完成:

您创建一个新的int 2D-Array a:

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

您可以在:

中替换两个数组
a[0] = new int[2];// line 2
a[2] = new int[3];// line 3

您重新分配a并创建一个新数组:

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

在第3行之后,您将在第2行和第3行中更换两个阵列。

在第4行之后,垃圾收集器将拾取放置在“旧”a中的每个对象(数组),因此4个对象(int 一个对象,请参阅Konstantins回答{{3 }})。

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

我希望我做对了;)

答案 1 :(得分:1)

当程序不再对对象有任何引用时,就会发生垃圾收集,而不是在创建对象时,所以"当我们创建一个数组数组时#34;垃圾收集没有任何反应。

基元的二维数组,如int[][],由一个对象数组组成,其中包含对 n int[]数组的引用(其中 n 是外部数组的大小 - 在示例的第1行中为4)。当您将该二维数组分配给a时,您将创建从a到外部数组的引用,并依次创建到内部基本数组,因此垃圾收集器不会删除任何这些对象。

在第二行,您构造一个新的int[],然后将其分配给外部数组的第一个索引。此赋值(不是数组的创建)导致先前分配给索引int[]的{​​{1}}有资格进行垃圾回收,因为不再有任何方法可以引用它 - 它是"垃圾"

第三行是相同的,你构造一个新的0然后将它分配给一个索引,删除对前面引用的数组的唯一引用。它现在也有资格收集。因此,在第三行之后,可以收集两个int[]个对象。

第四行构造一个新的int[],执行与上面相同的工作(一个对象数组包含 n int[][]数组),然后将该数组赋值给{{1} },从而删除对前一个二维数组的唯一引用。此时,GC可以看到没有任何东西引用旧阵列并清理它。一旦发生这种情况,内部阵列也没有剩余的引用,GC也可以清除它们。

在第四行之后,你仍然可以通过int[]引用这个新数组,然后依次引用它包含的数组。您之前构建的阵列不再可访问,因此最终将由GC清理。一旦GC有机会运行将留在内存中的所有内容都是由a引用的数组和它依次引用的内部数组。