Java SCJP问题:对象何时被垃圾回收?

Java SCJP问题:对象何时被垃圾回收?,java,garbage-collection,scjp,Java,Garbage Collection,Scjp,即使在得到正确答案后,我也无法找出SCJP问题: 根据以下代码(源代码:),我们需要确定引用为myInt的对象何时有资格进行垃圾收集: 01.public void doStuff() { 02. Integer arr[] = new Integer[5]; 03. for (int i = 0; i < arr.length; i++) { 04. Integer myInt = new Integer(i); 05. arr[i

即使在得到正确答案后,我也无法找出SCJP问题:

根据以下代码(源代码:),我们需要确定引用为myInt的对象何时有资格进行垃圾收集:

01.public void doStuff() {  
02.    Integer arr[] = new Integer[5];  
03.    for (int i = 0; i < arr.length; i++) {  
04.        Integer myInt = new Integer(i);  
05.        arr[i] = myInt;  
06.    }  
07.    System.out.println("end");  
08.}
01.public void doStuff(){
02.整数arr[]=新整数[5];
03.对于(int i=0;i

答复表明,它有资格获得第6行的GC。但我认为,直到第7行之后,该对象才可用于GC。因为,被引用为myInt的对象也被称为arr[i]。所以,您不认为,因为在myInt超出范围后,arr[]在第8行之前仍然有一个对它的引用吗?

arr[i]=myInt
创建了对
新整数(i)
的引用的副本,而不是对
myInt
的引用;因此,在赋值之后并不严格要求myInt存在。

与流行的观点相反,Java对象变量包含对对象的引用,而不是对象本身。将一个对象变量指定给另一个对象变量时,将复制引用而不是对象。AFAIK GC用于对象而不是引用。我们都知道GC在不存在对它的引用时声明了一个对象


在我看来,
myInt
引用的对象在函数
doStuff
返回(第8行)之前不可用于收集。
myInt
引用的对象存储在
arr
中,该对象在函数返回之前一直在作用域中。

SCJP答案的原因是在第6行,
arr
的作用域中没有引用它的剩余语句。在正常情况下,这将使数组及其元素符合垃圾收集的条件

(Java语言规范(12.6.1)规定:

"可访问对象是可以从任何活动线程在任何可能的连续计算中访问的任何对象。可以设计程序的优化转换,以减少可访问对象的数量,使其少于那些被天真地认为可访问的对象。例如,编译器或代码生成器可以选择将不再使用的变量或参数设置为null,以使此类对象的存储可能更快地被回收。”

如您所见,可达性的真正定义实际上并不基于范围。)


这个问题还有另一个转折点

如果他们已将
i
分配给
myInt
,则自动装箱将使用
Integer.valueOf(i)
,并且该方法会将
Integer
对象记录在
静态
缓存中。此缓存将导致该对象保持可访问状态


但是,
Integer
实例是使用
new
创建的,因此不会发生缓存。并且在第6行无法访问该对象。
arr
myInt
最后一次引用是在第5行。由于第7行没有引用它,我可以看出为什么第6行是声明的答案。

来自:

可访问对象是可以从任何活动线程在任何可能的连续计算中访问的任何对象。可以设计程序的优化转换,以减少可访问对象的数量,使其少于那些通常认为可访问的对象。例如,编译器或代码生成器可以选择o将不再使用的变量或参数设置为null,以使此类对象的存储可以更快地回收


因此,在这个定义下,
arr
引用的数组在第6行之后被认为是不可访问的,因此它的元素也是不可访问的。

问题是关于
myInt
引用的对象……而不是对
myInt
的引用(事实上,在Java中,不能引用变量)。”与普遍的看法相反……。不太可能。没有人有半点线索相信:-)