JVM虚拟机垃圾回收中的finalization机制

finalization机制

在这里插入图片描述

JVM虚拟机再进行内存中的垃圾回收时,会先判断对象中的finalize()方法是否被重写,被重写的方法是否与GC Roots有直接或间接的联系,从而决定当前对象是否被回收,这就是JVM的finalization机制。

finalize()方法

finalize()方法允许在子类中被重写,用于在对象被回收时进行资源释放。
通常在这个方法中进行一些资源释放和清理的工作,比如关闭文件、套接字和数据库连接等。
finalize()方法由一个虚拟机自动创建的、低优先级的Finalizer线程触发待回收对象的finalize()方法执行,所以永远不要主动调用某个对象的finalize()方法,应该交给应圾回收机制调用,并且一个糟糕的 finalize()方法会影响系统GC的性能。

待回收对象的状态

由于finalize()方法的存在,虚拟机中的对象一般处于三种可能的状态:
如果从所有的根节点都无法访问到某个对象,说明对象己经不再使用了。一般来说,此对象需要被回收。但事实上,也并非是非死不可的,这时候它们暂时处于“缓刑”阶段。一个无法触及的对象有可能在某一个条件下“复活”自己,如果这样,那么对它的回收就是不合理的,为此,定义虚拟机中的对象可能的三种状态。如下:

  1. 可触及的:从根节点开始,可以到达这个对象。
  2. 可复活的:对象的所有引用都被释放,但是对象有可能在finalize()中复活。
  3. 不可触及的:对象的finalize()被调用,并且没有复活,那么就会进入不可触及状态。不可触及的对象不可能被复活,因为finalize()只会被调用一次。

以上3种状态中,是由于finalize()方法的存在,进行的区分。只有在对象不可触及时才可以被回收。

对象被回收的过程

判定一个对象。A是否可回收,至少要经历两次标记过程:

  1. 如果对象A到GCRoots没有引用链,则进行第一次标记。

  2. 进行筛选,判断此对象是否有必要执行finalize()方法I

    ①如果对象A没有重写finalize()方法,或者finalize()方法已经被虚拟机调用过,则虚拟机视为“没有必要执行”,A被判定为不可触及的。

    ②如果对象。A重写了finalize()方法,且还未执行过,那么A会被插入到F-Queue队列中,由一个虚拟机自动创建的、低优先级的Finalizer线程触发其finalize()方法执行。

    ③finalize()方法是对象逃脱死亡的最后机会,稍后GC会对F-Queue队列中的对象进行第二次标记。如果A在finalize()方法中与引用链上的任何一个对象建立了联系,那么在第二次标记时,A会被移出“即将回收”集合。之后,对象会再次出现没有引用存在的情况。在这个情况下,finalize方法不会被再次调用,对象会直接变成不可触及的状态,也就是说,一个对象的finalize方法只会被调用一次。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦里藍天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值