天天看点

Java 垃圾回收finalize()方法

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 或其他方式,都可以做的更好。完全不用使用这个方法。

继续阅读