Java——finalize()方法(不建议使用)

工作原理

一旦垃圾收集器准备好释放对象占用的存储空间,首先调用finalize(),而且只有在下一次垃圾收集过程中,才会真正回收对象的内存。
finalize()方法的通用格式如下:
Java允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。Java语言规范中不仅不保证终结方法会被及时地执行,而且根本不保证他们会被执行。
如果使用了终结方法,就记住一定要调用super.finalize()。记住一句话:避免使用终结方法–finalize()。可以在finalize()让这个对象再次被引用,避免被GC回收;但是最常用的目的还是做cleanup

finalize工作流程

回顾一下,Finalizable对象的生命周期和普通对象的行为是完全不同的,列举如下:

JVM创建Finalizable对象
JVM创建 java.lang.ref.Finalizer实例,指向刚创建的对象。
java.lang.ref.Finalizer类持有新创建的java.lang.ref.Finalizer的实例。这使得下一次新生代GC无法回收这些对象。
新生代GC无法清空Eden区,因此会将这些对象移到Survivor区或者老生代。
垃圾回收器发现这些对象实现了finalize()方法。因为会把它们添加到java.lang.ref.Finalizer.ReferenceQueue队列中。
Finalizer线程会处理这个队列,将里面的对象逐个弹出,并调用它们的finalize()方法。
finalize()方法调用完后,Finalizer线程会将引用从Finalizer类中去掉,因此在下一轮GC中,这些对象就可以被回收了。
Finalizer线程会和我们的主线程进行竞争,不过由于它的优先级较低,获取到的CPU时间较少,因此它永远也赶不上主线程的步伐。
程序消耗了所有的可用资源,最后抛出OutOfMemoryError异常。

为什么不能显示直接调用finalize方法?

finalize方法在垃圾回收时一定会被执行,而如果在此之前显示执行的话,也就是说finalize会被执行两次以上,而在第一次资源已经被释放,那么在第二次释放资源时系统一定会报错,因此一般finalize方法的访问权限和父类保持一致,为protected。

Java中为什么在重写finalize()方法时首选调用super.finalize()?
 @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("一个 Cat 被销毁");
    }

super是用在子类中,目的是访问直接父类中被屏蔽的成员。

调用super.finalize(),父类中finalize如果有关闭资源的逻辑,当子类中finalize没有显示调用super.finalize()时父类的finalize不会被执行,所以父类的资源无法关闭。

带来的隐患

由于Finalizer线程优先级相较于普通线程优先级要低,而根据Java的抢占式线程调度策略,优先级越低的线程,分配CPU的机会越少,因此当多线程创建重写finalize方法的对象时,Finalizer可能无法及时执行finalize方法,Finalizer线程回收对象的速度小于创建对象的速度时,会造成F-Queue越来越大,JVM内存无法及时释放,造成频繁的Young GC,然后是Full GC,乃至最终的OutOfMemoryError。

@Override的作用

@Override是伪代码,表示重写。(不写@Override也可以)
写上的好处:
1、可以当注释用,方便阅读;
2、编译器可以给你验证@Override下面的方法名是否是你父类中所有的,如果没有则报错。例如,你如果没写@Override,而你下面的方法名又写错了,这时你的编译器是可以编译通过的,因为编译器以为这个方法是你的子类中自己增加的方法。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值