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行之后有多少对象符合垃圾收集器的条件。我已经搜索了解决方案,但我对找到的答案并不满意。
答案 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
引用的数组和它依次引用的内部数组。