首页 > 代码库 > java中的finalize()

java中的finalize()

    Java的垃圾回收器在回收某个对象的内存之前,会调用finalize()方法进行资源清理。
如果程序在终止之前始终没有进行垃圾回收,那么对象的finalize()是始终不会调用的。
    关于finalize()我们有以下几点说明:

  • 1.永远不要主动的去掉用对象的finalize(),交给垃圾回收机制去调用
  • 2.finalize()是否被调用和何时被调用都有不确定性
  • 3.如果JVM执行可恢复对象的finalize(),可能会使得该对象重新变成可达状态
  • 4.如果JVM执行finalize方法时出现异常,垃圾回收机制不会报告异常,程序继续执行
    下面给出一段测试代码,来演示对象从可恢复状态转换成可达状态的情况。
public class StringDemo {
	private static StringDemo demo = null;
	public static void main(String[] args) {
		System.out.println("new=" + new StringDemo());
		System.out.println("new=" + new StringDemo());
		System.out.println("new=" + new StringDemo());
		System.gc();
		System.runFinalization();
		demo.info();
	}
	public void info() {
		System.out.println("-----info-----");
	}
	@Override
	protected void finalize() throws Throwable {
		demo = this;
		System.out.println("this=" + this);
		System.out.println("demo=" + demo);
	}
}  

    在主函数中,我定义了三个StringDemo匿名对象,这三个对象都是在堆内存里面,没有任何引用变量指向它们,也就是一初始化之后就处于可恢复状态。在这之后,调用System.gc(),通知JVM该收垃圾了,但是在下面紧接着调用了System.runFinalization(),这个方法会强制垃圾回收期调用系统中可恢复对象的finalize(),因此,在被回收之前,调用了每个匿名对象的finalize()方法。在finalize()里面我做了什么呢?我把一个静态的StringDemo变量指向了自身,这样demo就不是null了,所以在demo.info();方法的时候,可以正常输出,也就是转换成了可达状态,然后程序结束了。

    如果不添加System.runFinalization();那么demo就是null,程序就会空指针异常。

    下面是程序运行的结果
技术分享

java中的finalize()