对象的finalization机制
理解了GC Roots和引用类型的概念后,也就知道了那些对象可以被回收,那些对象那个不能回收
有GC Roots引用的对象不能回收,没有GC Roots引用的对象可以回收,如果有GC Roots引用,但是如果时软引用或者是弱引用,一样也可能会被回收
注意:如果没有GCRoots引用的对象,是不一定会被马上回收的,还可以通过Finalization机制来进行处理
如果对象重写了finalize()方法,如下面示例:这时候对象可以进行自我拯救
/**
* @Author: DearSil
* @Date: 2023/4/24 14:18
* @Version: 1.0
* @Description:
* 下面这段代码演示了两点
* 1.对象可以在被GC的时候自我拯救
* 2.着各种自救的机会只有一次,因为一个对象的finalize()方法最多只会被系统自动调用一次
* 一个类可以重写finalize()方法,在方法里面自救或者做一些其他的事情,这个方法
* 会在GC的时候被JVM自动调用
*/
public class TestFinalization {
public static TestFinalization testFinalization;
@Override
protected void finalize() throws Throwable {
System.out.println("当前的对象正在被回收,执行finalize()方法");
testFinalization = this;
}
}
注意:上述对象自救的机会只有一次,GC在回收对象的时候只会调用一次该对象的finalize()方法,第二次就直接清除了
注意
- 永远不要主动调用某个对象的finalize()方法,应该交给GC来调用,理由有
- 在finalize()时可能会导致对象复活
- fingalize()方法的执行时间是没有保障的,他完全是由GC线程决定的,极端情况下,如果不发生GC,则finalize()方法将没有执行机会
- 一个糟糕的finalize()会严重影响GC的性能
- 从功能上来说,finalize()方法会与C++中的析构函数比较类似,但是java采用的是基于垃圾回收器的自动内存管理机制,所以finalize()方法本质上不同于C++的析构函数
- 其次他的运行代价高昂,不确定性打,无法保证各个对象的调用顺序,如今已经被官方明确声明为不推荐使用的语法,有些教材中描述它适合做“关闭外部资源”之类的请理性工作,这完全是对finalize()方法用途的一种自我安慰,finalize()能做的所有工作,使用try-finally或者其他的方法都可以做得更好更及时,所以建议大家可以忘掉这个方法