说明:文章所有内容均摘自《深入理解Java虚拟机:JVM高级特性与最佳实践(第二版)》


即使在可达性分析算法中不可达的对象,也并非是“非死不可”的,这时候它们暂时处于“缓刑”阶段。

要真正宣告一个对象死亡,至少要经历两次标记过程:如果对象在进行可达性分析后发现没有与GC Roots相连接的引用链,那它将会被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法。当对象没有覆盖finalize()方法,或者finalize()方法已经被虚拟机调用过,虚拟机将这两种情况都视为“没有必要执行”。

如果这个对象被判定为有必要执行finalize()方法,那么这个对象将会放置在一个叫做F-Queue的队列之中,并在稍后由一个由虚拟机自动建立的、低优先级的Finalizer线程去执行它。这里所谓的“执行”是指虚拟机会触发这个方法,但并不承诺会等待它运行结束,这样做的原因是,如果一个对象在finalize()方法中执行缓慢,或者发生了死循环(更极端的情况),将很可能会导致F-Queue队列中其他对象永久处于等待,甚至导致整个内存回收系统崩溃。finalize()方法是对象逃脱死亡命运的最后一次机会,稍后GC将对F-Queue中的对象进行第二次小规模的标记,如果对象要在finalize()中成功拯救自己——只要重新与引用链
上的任何一个对象建立关联即可,譬如把自己(this关键字)赋值给某个类变量或者对象的成员变量,那在第二次标记时它将被移除出“即将回收”的集合;如果对象这时候还没有逃脱,那基本上它就真的被回收了。从代码清单3-2中我们可以看到一个对象的finalize()被执行,但是它仍然可以存活。

/*** 此代码演示了两点:* 1.对象可以在被GC时自我拯救。* 2.这种自救的机会只有一次,因为一个对象的finalize()方法最多只会被系统自动调用一次**/
public class FinalizeEscapeGC {public static FinalizeEscapeGC SAVE_HOOK = null;public void isAlive() {System.out.println("yes,i am still alive:)");}@Overrideprotected void finalize() throws Throwable {super.finalize();System.out.println("finalize mehtod executed!");FinalizeEscapeGC.SAVE_HOOK = this;}public static void main(String[] args) throws Throwable {SAVE_HOOK = new FinalizeEscapeGC();//对象第一次成功拯救自己SAVE_HOOK = null;System.gc();//因为finalize方法优先级很低,所以暂停0.5秒以等待它Thread.sleep(500);if (SAVE_HOOK != null){SAVE_HOOK.isAlive();}else{System.out.println("no,i am dead:(");}//下面这段代码与上面的完全相同,但是这次自救却失败了SAVE_HOOK = null;System.gc();//因为finalize方法优先级很低,所以暂停0.5秒以等待它Thread.sleep(500);if (SAVE_HOOK != null){SAVE_HOOK.isAlive();}else{System.out.println("no,i am dead:(");}}
}运行结果:
finalize mehtod executed!
yes,i am still alive:)
no,i am dead:(

从代码清单3-2的运行结果可以看出,SAVE_HOOK对象的finalize()方法确实被GC收集器触发过,并且在被收集前成功逃脱了。

另外一个值得注意的地方是,代码中有两段完全一样的代码片段,执行结果却是一次逃脱成功,一次失败,这是因为任何一个对象的finalize()方法都只会被系统自动调用一次,如果对象面临下一次回收,它的finalize()方法不会被再次执行,因此第二段代码的自救行动失败了。

需要特别说明的是,上面关于对象死亡时finalize()方法的描述可能带有悲情的艺术色彩,笔者并不鼓励大家使用这种方法来拯救对象。相反,笔者建议大家尽量避免使用它,因为它不是C/C++中的析构函数,而是Java刚诞生时为了使C/C++程序员更容易接受它所做出的一个妥协。它的运行代价高昂,不确定性大,无法保证各个对象的调用顺序。有些教材中描述它适合做“关闭外部资源”之类的工作,这完全是对这个方法用途的一种自我安慰。finalize()能做的所有工作,使用try-finally或者其他方式都可以做得更好、更及时,所以笔者建议大家完全可以忘掉Java语言中有这个方法的存在。

【深入Java虚拟机JVM 09】JVM垃圾回收finalize方法--对象最有一次自我拯救相关推荐

  1. java虚拟机内存模型与垃圾回收知识复习总结

    今天日子很特殊,1024程序员节,本来每个月计划的是至少一篇博客,刚好这个月还没写,今天的日志又特殊,必须要写一篇博客. 之前看过一些讲java虚拟机的课程,但是学过容易忘,总结一下,平时可以多看看. ...

  2. Java虚拟机(二)——垃圾回收与内存分配

    文章目录 垃圾回收与内存分配 1 引用 2 如何判断对象需要回收 2.1 引用计数算法 2.2 可达性分析算法 2.3 废弃常量的回收 2.4 无用的类的回收 3 内存分配 4 垃圾收集算法 4.1 ...

  3. 《Java虚拟机内幕揭秘:垃圾回收的奇妙世界》

    16_垃圾回收相关概念 System.gc()的理解 在默认情况下,通过system. gc ()或者Runtime.getRuntime ( ).gc ( )的调用,会显式触发Full GC,同时对 ...

  4. Java虚拟机(十三)——垃圾回收概述

    文章目录 概述 什么是垃圾 为什么需要GC 早期垃圾回收 Java垃圾回收机制 大厂面试题: 蚂蚁金服: 百度: 天猫: 滴滴: 京东: 阿里: 字节跳动 概述 垃圾收集,不是Java语言的伴生产物, ...

  5. JAVA之JVM分代垃圾回收策略(一)

    一.为什么要分代 分代的垃圾回收策略,是基于这样一个事实:不同的对象的生命周期是不一样的.因此,不同生命周期的对象可以采取不同的收集方式,以便提高回收效率. 在Java程序运行的过程中,会产生大量的对 ...

  6. Java对象垃圾回收调用,JVM垃圾回收之哪些对象可以被回收

    1.背景 Java语言相比于C和C++,一个最大的特点就是不需要程序员自己手动去申请和释放内存,这一切交由JVM来完成.在Java中,运行时的数据区域分为程序计数器.Java虚拟机栈.本地方法栈.方法 ...

  7. 推荐收藏系列:一文理解JVM虚拟机(内存、垃圾回收、性能优化)解决面试中遇到问题(图解版)

    欢迎一起学习 <提升能力,涨薪可待篇> <面试知识,工作可待篇 > <实战演练,拒绝996篇 > 欢迎关注我csnd博客 也欢迎关注公 众 号[Ccww笔记],原创 ...

  8. Java进阶 JVM 内存与垃圾回收篇(一)

    JVM 1. 引言 1.1 什么是JVM? 定义 Java Vritual Machine - java 程序的运行环境(Java二进制字节码的运行环境) 好处 一次编译 ,到处运行 自动内存管理,垃 ...

  9. java虚拟机_一文彻底读懂Java虚拟机!(JVM)

    提到Java虚拟机(JVM),可能大部分人的第一印象是"难",但当让我们真正走入"JVM世界"的时候,会发现其实问题并不像我们想象中的那么复杂.唯一真正令我们恐 ...

最新文章

  1. 开发日记-20190619 关键词 读书笔记《鸟哥的Linux私房菜-基础学习篇》
  2. ccf a类会议_ISCA#39;21截稿在即,阿里或成为国内在该会议上的最大赢家!
  3. 业界 | 复杂出行场景下,滴滴如何将AI融入地图系统
  4. 《计算复杂性:现代方法》——0.2 判定问题/语言
  5. python knnmatch_opencv python 特征匹配
  6. skynet源码分析5:lua绑定之地基
  7. php firefox导出csv,如果文件名有空格,空格后面部分不会导出,后缀也没有
  8. jQuery获取鼠标事件源(万能)
  9. gsonformat java代码_GSONFormat的简单使用
  10. 密码学系列——NTHASH以及MD4算法
  11. 编程中,有哪些好的习惯从一开始就值得坚持?
  12. 大数据面试3分钟自我介绍_[持续更新]渣渣大数据社招面试之路
  13. logback配置信息详解
  14. 计算机几大管理器,电脑里的任务管理器的快捷键是按哪几个键?
  15. iphone访问限制密码忘记了怎么办
  16. 那些我接触过的「小而美」的公司
  17. 7-3 地下迷宫探索(30 分)(dfs)
  18. 易语言如何调用c dll文件,易语言调用C++写的DLL
  19. 耳机不分主从是什么意思_音质出色,降噪服众,千元机档位王者南卡A1主动降噪耳机深度评测...
  20. 2D-Driven 3D Object Detection in RGB-D Images

热门文章

  1. 决策树 bagging boosting 的区别
  2. Html 教程 (3)元素
  3. java面试题2(java基础)
  4. 近世代数--整环上的整除理论--主理想整环中最大公因子的存在表示定理
  5. 初等数论--整除--整数表示:算数分解定理/素因数分解式/进制表示
  6. 操作系统课设--扩展文件系统
  7. gdb+pwndbg使用初探
  8. UnboundLocalError: local variable ‘XXX‘ referenced before assignment解决办法
  9. Dockerfile项目环境介绍
  10. (33)调试驱动程序