您的位置:首页 > 其它

垃圾回收之对象的死亡过程

2018-01-25 15:43 162 查看
当触发垃圾回收时,GC(垃圾回收)线程会根据跟搜索算法判断这个对象是否可达(即GCroot到这个对象之间时否有一条可达的引用链)。

如果可达,很幸运,你继续活着。

如果不可达,当然你不一定百分之一百就死掉了,在杀死一个对象之前,GC线程至少会对这个对象标记两次,

垃圾回收线程在对所有不可达的对象进行第一次标记后,会进行一个筛选,

筛选的条件是:是否执行这个对象的fianlize()方法。这个方法是Object对象自带的,所以每个对象也都包含此方法。

如果 对象的fianlize()方法被这个对象覆盖,或者这个对象的finalize()方法是否被虚拟机调用过。

则则被判断为很有必要调用对象的fianlize()方法。

如果被判断有必要执行对象的fianlize()方法,那么这个对象会被放入一个叫做F-Queue的队列中,

稍后会有虚拟机自动创建一个低优先级的fianlizer的线程,此线程回去触发队列中对象的fianlize()方法,

但是不保证等待对象的finalize()方法执行结束,因为万一对象的这个方法执行的非常缓慢,甚至极端的出现了死循环,

会影响F-Queue队列中的其他对象的处理,甚至导致整个垃圾回收崩溃。

因为对象的finalize()方法会被调用,又可以被重写,所以这是这些对象逃离升天不被垃圾回收kill的唯一的一次机会。

如果这些对象重写了自己的finalize()方法,并且顺利的把自己重新复制给一个新的引用,

这样的话就有了GCroot指向此对象,再第二次进行垃圾回收的时候就可以逃离升天了。

如果再这个方法中没有给自己找一个新的归属,就真的离死亡不远了,GC线程的死亡之镰会挥舞向你。

注意:请尽量不要复写这个finalize(),用它来拯救对象,因为运行他的代价太大,不确定性也很大,对象的执行顺序也不一样。

至于用它来关闭资源,这只是一个自我安慰。try catch finally 效果更好也更容易把控。所以可以把这个方法完全忘记。

GCroot主要包括以下几类:

1.虚拟机栈(栈中的本地变量表)中引用的对象。

2.方法区中类静态属性引用的对象。

3.方法区中常量引用的对象。

4.本地方法栈中JNI(即常说的native方法中)引用的对象
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐