《JAVA程序员面试宝典》86页,有这样一道关于垃圾回收机制的li
下列代码中,第几行的obj符合垃圾收集器的收集标准?[SAP公司2005年10月面试题]
下列代码中,第几行的obj符合垃圾收集器的收集标准?[SAP公司2005年10月面试题]
1. Object aobj = new Object();
2. Object bobj = new Object();
3. Object cobj = new Object();
4. aobj = bobj;
5. aobj = cobj;
6. cobj = null;
7. aobj = null;
给出的解析说了很多:
同时在网上也看到了大家的一些争议,主要的争议点在aobj是否也被回收了。因为在执行了第4句后,aobj对象已经失去了所有的引用。看到有朋友用下面的代码进行了论证。证明aobj也被回收了。
package com.example.rubbish;
public class Rubbish {
private static int i=0; private int j = 0;
public Rubbish() {
// TODO Auto-generated constructor stub
j = i;
i++;
}
protected void finalize() {
System.out.println(j);
}
/** * @param args */
public static void main(String[] args) {
// TODO Auto-generated method stub
Object aobj = new Rubbish ( );
Object bobj = new Rubbish ( );
Object cobj = new Rubbish ( );
System.gc();
System.out.println("第三行垃圾处理");
aobj = bobj;
System.gc();
System.out.println("第四行垃圾处理");
aobj = cobj;
System.gc();
System.out.println("第五行垃圾处理");
cobj = null;
System.gc();
System.out.println("第六行垃圾处理");
aobj = null;
System.gc();
System.out.println("第七行垃圾处理");
}}
运行结果:
第三行垃圾处理
第四行垃圾处理
0
第五行垃圾处理
第六行垃圾处理
第七行垃圾处理
2
最后输出了一个2,证明两个对象被回收了。那么根据以上论证,是否证明书上给的答案错了呢?是否第4行也符合垃圾回收机制呢?
我个人并不认同。我看到网上很多人判断对象是否会对回收的标准是,只要对象没有被引用就会被回收。但我看到书上给的标准不太一样。
以此标准来看,虽然第4行执行以后aobj对象失去了引用。但并没有被赋予空值,也没有赋予新值。所以并不符合收集标准。因此只有第7行符合标准,为正确答案。
同时也看到了另一种解释,同样支持正确答案只有第7行。
虽然aobj对象产生的内存没有被任何变量引用,但java虚拟机的垃圾处理器不能自动清理,除非内存不够才会开始清理,只有当你将new object()赋给某个变量的时候垃圾处理器才会自动清理,当然你可以用System.gc()去手动回收垃圾,但手动回收并不能保证立即回收指定对象。
这样就不难理解为什么上面的验证代码最后输出的结果是2了。这里恰恰是因为使用了手动回收。