1.Demo
package com.weizhi.gc.test;
/*
*1.对象可以在Gc时自我拯救
*2.这种机会只有一次,因为对象的finalize()方法只会被系统自动调用一次
*/
public class GcFinalize {
private static GcFinalize gcFinalize = null;
public void isAlive(){
System.out.println("alive...");
}
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("finalize method executed!");
GcFinalize.gcFinalize = this;
}
public static void main(String[] args) throws InterruptedException {
gcFinalize = new GcFinalize();
gcFinalize = null;
System.gc();
//finalize 方法优先级很低,需要等待0.5s
Thread.sleep(500);
if(gcFinalize!=null){
gcFinalize.isAlive();
}else{
System.out.println("dead...");
}
//第二次回收
gcFinalize = null;
System.gc();
Thread.sleep(500);
if(gcFinalize!=null){
gcFinalize.isAlive();
}else{
System.out.println("dead...");
}
}
}
输出:
finalize method executed!
alive...
dead...
2.解析
1.从demo中运行结果可以看出,gcFinalize对象的finalize()方法的确被GC收集器触发过,并且在被收集之前成功逃脱了。
2.代码中有两段完全一样的代码,执行结果却是一次逃脱成功,一次失败,这是因为任何一个对象的finalize()方法都会只被系统自动调用一次,如果对象面临下一次回收,它的finalize()方法都不会被再次执行,因此第二段代码的自救行动失败了。
3.finalize()方法运行代价高,不确定性大,无法保证每个对象的调用顺序,finalize()方法能做的所有工作,使用try-finally 或其他方式,都可以做的更好。完全不用使用这个方法。