009-JVM-对象的finalization机制

上一篇:008-JVM-清除阶段算法之三:标记-压缩算法Mark-Compact
https://blog.csdn.net/fsjwin/article/details/111342195

标记为不可达的对象一定会被回收吗?
这是一个好问题,一般这么问的答案肯定是否定的!!!
Object.java 中的方法:

 protected void finalize() throws Throwable { }

1. finalization机制存在的必要性

finalization机制简单说就是免死金牌,或者在沙头前的一道圣旨。

  • Java 语言提供了对象终止(finalization) 机制来允许开发人员提供对象被销毁之前的自定义处理逻辑。
  • 当垃圾回收器发现没有引用指向一个对象, 即: 垃圾回收此对象之前, 总会先调用这个对象的finalize()方法。
  • finalize()方法允许在子类中被重写, 用于在对象被回收时进行资源释放(当然也可以随便做些事情如,不让他回收,让他重新复活)。通常在这个方法中进行一些资源释放和清理的工作, 比如关闭文件、套接字和数据库连接等。

2. 永远不要主动调用某个对象的finalize()方法

  • 永远不要主动调用某个对象的finalize()方法, 应该交给垃圾回收机制调用。理由包括下面三点:
  • 在finalize() 时可能会导致对象复活
  • finalize() 方法的执行时间是没有保障的, 它完全由GC 线程决定, 极端情况下,若不发生GC , 则finalize() 方法将永远没有执行机会
    一个糟糕的 finalize() 会严重影响GC 的性能

3. 生存还是死亡

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

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

4. 专门的线程收集垃圾

有一个优先级比较低的线程,专门调用finalize()方法在这里插入图片描述

5. 具体过程

  • 判定一个对象。obj 是否可回收, 至少要经历两次标记过程:
  1. 如果对象obj 到GC Roots 没有引用链, 则进行第一次标记
  2. 进行筛选, 判断此对象是否有必要执行finalize()方法。
    (1)如果对象obj没有重写 finalize() 方法, 或 finalize() 方法己经被虚拟机调用过,则虚拟机视为“ 没有必要执行” 。obj被判定为不可触及的
    (2) 如果对象obj重写了 finalize() 方法, 且还未执行过, 那么obj会被插入到F-Queue队列中, 由一个虚拟机自动创建的、低优先级的 finalizer线程触发其 finalize() 方法执行。
    (3) finalize() 方法是对象逃脱死亡的最后机会, 稍后GC 会对F-Queue 队列中的对象进行第二次标记: 如果obj在 finalize() 方法中与引用链上的任何一个对象建立了联系,那么在第二次标记时,obj会被移出“ 即将回收 F-Queue” 集合。
  3. 之后, 对象会再次出现没有引用存在的情况。在这个情况下 finalize() 方法不会被再次调用, 对象会直接变成不可触及的状态, 也就是说, 一个对象的 finalize() 方法只会被调用一次

6. 复活演示

关键点:finalize()方法中和gc roots中的对象发生关系,就可免一死!
在这里插入图片描述
下一篇:010-JVM-Java从编译到执行的流程 https://blog.csdn.net/fsjwin/article/details/111404949

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值