jvm杂谈(一)-- 浅谈对象已死

本文主要是简单的聊聊一个对象如何被判断死亡,这个很重要,因为被判断死亡后,要被垃圾收集自动回收,然后就尘归尘土归土,再也无法复活。

        首先,判断对象已死的方法有哪些,一般情况有如下两种:

         1、引用计数

         这个很简单,就是new了一个对象,谁引用我,就加1,这样一直累加,如果这个引用用完了,不引用了,就减1,这样一直累减,当计数为零的时候,判断该实例对象没有存活的价值,可以判定位死刑了。但是这个方法有个致命的问题,就是没办法解决两个对象的相互引用,虽然它简单高效,被python等很多语言使用,但是jvm没有采用种方法就判断对象已死。

         2、可达性分析

         什么叫可达性分析,就是我先规定一个路径的起始点,叫“GC ROOTS”。也可以理解为一个引用变量,如果一个对象实例可以根据它的引用路径可以到达这个起始点,那么它就是存活的,否则就是已死的。例如,A是一个方法的局部变量,引用了实例对象B,B里的变量引用了实例对象C,当方法未执行完毕时,我们认为从C或B都可以到达A(GC ROOTS),这样B和C对象实例是存活状态;如果方法执行完毕,A变量被销毁,这样B和C都是游离状态,没有GC ROOTS可以到达,则B和C实例对象就可以被判死亡了。jvm中就是选用可达性分析算法来判断java对象是否已死的。

       其次,我们既然是用可达性判断对象已死,那么,如何确定谁是GC ROOTS呢?一般常见的如下三种

       1、对象中的静态属性

       2、对象中的常量属性

       3、方法里面的局部变量

       最后,是不是我们判断java对象已死,就可以直接把它回收掉了呢?

       答案也不是肯定的,这个要看对象是否重载finalize方法,且被jvm调用了,这个方法可以认为是对象的最后一个救命稻草,如果执行完这个方法,还不能发现对象被其他GC ROOTS引用,那么它就可以被回收了。finalize类似一种缓刑,就是会被jvm放到一个低优先级的队列中等待执行,如果被执行完毕,仍无GC ROOTS引用,直接会被回收;即使自救成功,就是检测到了GC ROOTS,等到第二次检测时,该方法将不会被调用,会被jvm直接判断为死刑。

         值得注意的是finalize方法建议不要使用,因为try finally会做的更好,更及时。

        感谢大家的关注,本文为了更容易让大家理解,更改了很多专业术语,如果有什么误解可以回复讨论,如果喜欢请点赞和关注,谢谢!

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值