public class Book {
boolean checkout = false;
Book(boolean checkout){
this.checkout = checkout;
}
void checkIn(){
checkout = false;
}
protected void finalize(){
if(checkout){
System.out.println("Error: Check out!");
}
}
}
public class TerminationCondition {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Book novel = new Book(true);
novel.checkIn();
new Book(true);
System.gc();
}
}
代码如上所示, 实际在eclipse中运行时,偶尔会输出"Error: Check out!",而不是每次都输出,请问一下这是为什么呢? 难道System.gc()不是每次执行的时候都会调用finalize()方法吗?
------解决方案--------------------
楼主可以产生大量对象,不用System.gc(),会看到finalize()方法也运行。
------解决方案--------------------
个人理解,不保证正确:
可能是主线程先执行完了,导致看不到打印结果
可以在System.gc();后面加点东西看看效果。
参考api里的System.gc(),最好看英文的,中文版翻译的可能有错误。
------解决方案--------------------
首先:system.gc()并不是你调用就马上执行的, 而是根据虚拟机的各种算法来来计算出执行垃圾回收的时间,另外,程序自动结束时不会执行垃圾回收的。
其次:对象被回收时,要经过两次标记,第一次标记,如果finalize被重写,或者finalize被调用过,那么垃圾回收并不会去执行finalize,第二次标记,如果对象不能在finalize中成功拯救自己,那真的就要被回收了
这里说得比较简单,要想深入理解,请参见《深入理解java虚拟机+jvm高级特性与最佳实践》中的垃圾收集器与内存分配策略,再次,请你运行一下一下代码:
public class FinalizeEscapeGC {
public static FinalizeEscapeGC gc=null;
public static void isAlive(){
System.out.println("yes,i am alive!!!");
}
public static void isDead(){
System.out.println("no, i am dead!!!");
}
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("Finalize method is executed!!!");
gc=this;
}
public static void main(String[] args) throws Throwable{
gc=new FinalizeEscapeGC();
gc=null;
System.gc();
Thread.sleep(500);
if(gc!=null)
isAlive();