JVM基础-> GC如何判断对象可以被回收

16 篇文章 3 订阅

GC如何判断对象可以被回收

  • 引⽤计数法(已被淘汰):每个对象有⼀个引⽤计数属性,新增⼀个引⽤时计数加1,引⽤释放时计数减1,计数为0时可以回收

    • 目前主流的java虚拟机都摒弃掉了这种算法
    • 虽然循环引用的问题可通过 Recycler 算法解决,但是在多线程环境下,引用计数变更也要进行昂贵的同步操作,性能较低
    • 会出现循环引用问题不要在说了大哥们
  • 可达性分析法:从 GC Roots 开始向下搜索,搜索所⾛过的路径称为引⽤链。当⼀个对象到 GC Roots 没有任何引⽤链相连时,则证明此对象是不可⽤的,那么虚拟机就判断是可回收对象。

    • 目前主流的编程语言(java,C#等)的主流实现中,都是通过可达性分析来判定对象是否存活的。

对象object 5、object 6、object 7虽然互相有关联,但是它们到GC Roots是不可达的,所以它们将会被判定为是可回收的对象,等待垃圾回收。

这里写图片描述

GC Roots的对象有:

  • 虚拟机栈中引⽤的对象 -> 堆中的对象与栈之间没有任何引用

  • ⽅法区中类静态属性引⽤的对象 -> 堆中的对象与静态属性没有任何引用

  • ⽅法区中常量引⽤的对象 -> 堆中的对象与常量没有任何引用

  • 本地⽅法栈中Native⽅法引⽤的对象 -> 堆中的对象与本地⽅法栈没有任何引用

堆中的对象在四个地方都没有任何引用时,表示是可以被回收的

被GC判断为”垃圾”的对象一定会回收吗?

堆中的对象在四个地方都没有任何引用时,对象一定会被回收吗?

答:即使在可达性分析算法中不可达的对象,也并非是“非死不可”的。对象拥有一次⾃我拯救的机会。

对象被系统宣告死亡⾄少要经历两次标记过程:

  • 第⼀次是经过可达性分析发现没有与GC Roots相连接的引⽤链

    • 表示可以被回收了,但是有一次⾃我拯救的机会
  • 第⼆次是在由虚拟机⾃动建⽴的Finalizer队列中判断是否需要执⾏finalize()⽅法。

    • finalize()⽅法是Object类中的方法,作用就是用来对象被回收时可以被拯救用的。
    public class Object {
        protected void finalize() throws Throwable { }
    }
    
    • 当对象变成(GC Roots)不可达时,GC会判断该对象是否覆盖(重写)了finalize⽅法,若未覆盖,则直接将其回收。
    • 否则,若对象未执⾏过finalize⽅法,将其放⼊F-Queue队列,由⼀低优先级线程执⾏该队列中对象的finalize⽅法。
      • 这个方法只能被执行一次,只能有一次加入队列的机会,从队列出去就不会再被加入队列了
    • 执⾏finalize⽅法完毕后,GC会再次判断该对象是否可达,若不可达,则进⾏回收
    • 否则,对象“复活”

由于finalize()⽅法运⾏代价⾼昂,不确定性⼤,⽆法保证各个对象的调⽤顺序,不推荐⼤家使⽤,建议遗忘它。

public class TestMain {
    public static void main(String[] args) {
        Test test = new Test();
        // 第一次调用垃圾回收
        // 对象为null,第一次标记为可以被回收,但此次调用finalize()不会被真正回收
        test = null;
        System.gc();

        // 第二次调用垃圾回收
        // 对象为null,第二次不能再加入队列也不能再执行finalize()了,被真正回收了
        test = null;
        System.gc();
    }
}

class Test {
    //GC Roots: 来自静态属性
    public static Object object = null;

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        //引用静态属性
        object = this;
    }
}

补充知识

  • 可达性分析算法中枚举根节点(GC Roots)会导致所有Java执行线程停顿,进入STW状态
    • STW: Stop-The-World: 是在垃圾回收算法执⾏过程当中,将JVM内存冻结丶应用程序停顿的⼀种状态

点赞,靓仔!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值