深入理解finalize()方法—对象生存还是死亡
回收算法:可达性分析算法与计数算法
基于计数算法的缺点,同时可达性算法为主流回收算法的原因
以下我们以可达性算法为例:
即使在可达性分析算法中不可达的对象,也并非是“非死不可”的,这时候它们暂时处于“缓刑”阶段,要真正宣告一个对象死亡.至少要经历两次标记过程:如果对象在进行可达性分析后发现没有与GC Roots相连接的引用链,那它将会被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法。
有两种判断方式:①当对象没有覆盖finalize()方法(如果不覆盖方法,则可以理解为默认调用);②finalize()方法已经被虚拟机调用过(因为只会调用一次finalize()方法,不会再次调用(一般调用过还存活,说明覆盖了finalize()方法)),虚拟机将这两种情况都视为“没有必要执行”。
如果这个对象被判定为有必要执行finalize()方法(一般为覆盖了finalize()方法),那么这个对象将会放置在一个叫做F-Queue的队列之中,并在稍后由一个由虚拟机自动建立的、低优先级的Finalizer线程去执行它.这里所谓的“执行”是指虚拟机会触发这个方法,但并不承诺会等待它运行结束,这样做的原因是.如果一个对象在finalize()方法中执行缓慢,或者发生了死循环(更极端的情况).将很可能会导致F-Queue队列中其他对象永久处于等待,其至导致整个内存回收系统崩溃.finalize()方法是对象逃脱死亡命运的最后一次机会,稍后GC将对F-Queue中对象进行第二次小规模的标记.如果对象要在finalize()中成功拯救自己----只要重新与引用链上的任何一个对象建立关联即可,臂如把自己(this关键字)赋值给某个类变量或者对象

本文深入探讨了Java中的finalize()方法,讲解了对象如何从可达性分析算法的角度判断是否死亡,并经历两次标记过程。如果对象覆盖了finalize()方法并被判定需要执行,它会被放入F-Queue由Finalizer线程执行。尽管 finalize() 方法提供了让对象自救的机会,但不保证执行,且执行中抛出的异常会被忽略。Java对象通常在两次GC周期后,即使在finalize()中尝试自救失败,也会被清除。
最低0.47元/天 解锁文章
86万+

被折叠的 条评论
为什么被折叠?



