当对象获取垃圾时SCJP问题?

Cat*_*ish 2 java garbage-collection scjp

在得到正确答案之后,我无法弄清楚SCJP的问题:

从以下代码(来源:http://scjptest.com),我们需要确定何时被引用为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.}
Run Code Online (Sandbox Code Playgroud)

答案表明它符合第6行的GC条件.但我认为直到第7行之后,该对象根本不能用于GC.因为,被引用为myInt的对象也被称为arr [i].所以,你不觉得,因为,在myInt超出范围之后,arr []仍然会引用它直到第8行?

Ste*_*n C 5

SCJP答案的原因是,在第6行,其范围内没有剩余的陈述arr引用它.在正常情况下,这将使数组及其元素符合垃圾回收的条件.

(Java语言规范(12.6.1)说:

"可到达的对象是可以从任何活动线程的任何潜在的持续的计算访问的任何对象.优化程序的转换可以被设计为降低可达小于那些会天真地认为可以达到的对象的数量.例如,编译器或代码生成器可以选择设置一个不再用于null的变量或参数,以使这种对象的存储更快地被回收."

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


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

如果他们分配imyInt,自动装箱会使用Integer.valueOf(i),并且该方法将已经记录了Integer一个对象static缓存.此缓存会导致对象保持可访问性...

但是,Integer实例是使用创建的new,因此不会发生缓存.并且对象在第6行可达.