JVM进阶(六)——鲜为人知的二次标记

  上一章我们讲到了标记,但是不是被标记了就肯定会被回收呢?不知道小伙伴们记不记得Object类有一个finalize()方法,所有类都继承了Object类,因此也默认实现了这个方法。 
  finalize()方法:在该对象被回收之前,该对象的finalize()方法会被调用

  这里的回收之前指的就是被标记之后,问题就出在这里,有没有一种情况就是原本一个对象开始不在上一章所讲的“关系网”(引用链)中,但是当开发者重写了finalize()后,并且将该对象重新加入到了“关系网”中,也就是说该对象对我们还有用,不应该被回收,但是已经被标记啦,怎么办呢? 
  针对这个问题,虚拟机的做法是进行两次标记即第一次标记不在“关系网”中的对象。第二次的话就要先判断该对象有没有实现finalize()方法了,如果没有实现就直接判断该对象可回收;如果实现了就会先放在一个队列中,并由虚拟机建立的一个低优先级的线程去执行它,随后就会进行第二次的小规模标记,在这次被标记的对象就会真正的被回收了。我们来看下面的代码: 
 
  大家觉得他会输出什么?最后的结果是: 
    我被调用啦 
    我还活着 
    我挂啦 
  有木有觉得很诧异,明明调用了两次同样的方法,但输出怎么不同呢?而且明明调用了两次gc()方法(这里确认是执行了gc),那怎么只进入了一次finalize()方法? 
  嘿嘿,其实面对同一个对象,他的finalize()方法只会被调用一次,因此第一次调用的时候会进行finalize()方法,并且成功的将该对象加入了“关系网”中,但当第二次回收的时候并不会进入,所以第二次不能将对象加入“关系网”中,导致被回收了。 
   图中有一行让程序睡眠一秒钟的代码,为的就是确保让低优先级的执行finalize()方法线程执行完成。那如果我们把他注释了会怎样呢?输出结果是: 
    我挂啦 
    我被调用啦 
    我挂啦 
  很奇怪吧,不过如果执行很多次的话,也会出现最开始那样的结果,但多数会是这个结果。因为我们已经说了,执行finalize()的是一个低优先级的线程,既然是一个新的线程,虽然优先级低了点,但也是和垃圾收集器并发执行的,所以垃圾收集器没必要等这个低优先级的线程执行完才继续执行。也就是说,finalize()方法不一定会在对象第一次标记后执行。用一句清晰易懂的话来说就是:虚拟机确实有调用方法的动作,但是不会确保在什么时候执行完成。因此也就出现了上面输出的结果,对象被回收之后,那个低优先级的线程才执行完。

JVM进阶(六)——鲜为人知的二次标记相关推荐

  1. 【JVM进阶之路】二:Java内存区域

    1.运行时数据区 Java 虚拟机定义了若干种程序运行期间会使用到的运行时数据区,其中有一些会随着虚拟机启动而创建,随着虚拟机退出而销毁.另外一些则是与线程一一对应的,这些与线程对应的数据区域会随着线 ...

  2. JVM进阶(十二)——JAVA 可视化分析工具

    JVM进阶(十二)--JAVA 可视化分析工具   经过前几篇博文对堆内存以及垃圾收集机制的学习,相信小伙伴们已经建立了一套比较完整的理论体系!本篇博客就根据已有的理论知识,通过可视化工具来实践一番. ...

  3. 【JVM进阶之路】垃圾回收机制和GC算法之三色标记(三)

    JVM往期文章 [JVM进阶之路]内存结构(一) [JVM进阶之路]玩转JVM中的对象(二) 上篇文章中讲到JVM中的对象以及判断对象的存活,那么对于"已死"的对象应该如何处理,怎 ...

  4. JVM进阶(八)——Stop The World(停顿类型STW)

    JVM进阶(八)--Stop The World(停顿类型STW)   小伙伴还记得上一篇中我们留下的一个问题吗?什么是停顿类型!经过前几章的学习,我们知道垃圾回收首先是要经过标记的.对象被标记后就会 ...

  5. QIIME2进阶六_QIIME2训练分类器及物种注释

    本文我们主要介绍了如何训练Naive Bayes分类器并把这个分类器应用于扩增子基因序列的物种注释与可视化. 本教程将使用来自人源化(humanized)小鼠的一组粪便样品,展示16S rRNA基因扩 ...

  6. JVM进阶(一):初识 JAVA 栈

    文章目录 一.前言 二.栈存储 三.总结 四.延伸阅读 编译型语言与解释型语言 4.1 编译型语言 4.2 解释型语言 五.拓展阅读 一.前言 若想自己编写的Java程序高效运行,以及进行正确.高效的 ...

  7. 我所理解的JVM(六):内存回收

    2019独角兽企业重金招聘Python工程师标准>>> Java的一大特点就是虚拟机本身拥有垃圾回收机制,用户在编程过程中不再需要考虑垃圾回收的事情.所有的对象的创建都是在堆空间中, ...

  8. html语言标示,HTML语言剖析(二) HTML标记一览

    HTML语言剖析(二) HTML标记一览 2008-04-11 00:00:00 分享到: 摘要 :标记 类型 译名或意义 作 用 备注 文件标记 ● 文件声明 标记 类型 译名或意义 作 用 备注 ...

  9. python进阶06并发之二技术点关键词

    原创博客地址:python进阶06并发之二技术点关键词 GIL,线程锁 python中存在GIL这个"线程锁", 关键地方可以使用c语言解决 GIL问题 然后可以提高cpu占用效率 ...

  10. ILI9341的使用之【六】命令二

    由于ILI9341命令体系比较庞大,因此为了查询方便,把命令部分的解释分为两篇,本文为第二篇.第一篇详细解释了编码在3Fh以下的指令.本文详细解释编码在3Fh以上的指令. <ILI9341的使用 ...

最新文章

  1. 情绪管理的快速实践方法---视频学习记录
  2. java中的alert是什么意思_javascript 中如何使用alert?
  3. 【渝粤题库】广东开放大学 信息安全数学基础 形成性考核 (2)
  4. Win7下WinDbg开启Local Kernel Debug调试
  5. Oracle 12C -- 预定义audit policies
  6. 【英语学习】【Daily English】U11 Work L04 Can you keep it a secret?
  7. python的matplotlib库怎么安装_为Python安装matplotlib库
  8. [转] Asp.net mvc 3 beta 新特性介绍
  9. php无线级输出数据,thinkphp5.0无限极分类及格式化输出
  10. 有Excel、Tableau、PowerBI都能做数据分析,为什么还要用Python
  11. 动态服务器值 回放报错 没有关联到_LR之关联
  12. 皮尔逊Person相关系数
  13. 『UE4数字孪生』开发流程浅析(持续更新)
  14. 记录::Opencv调用tensorflow2.x-Keras模型
  15. 图片显示的优化以及blit
  16. 计算机硬件类的相关课程,计算机硬件类课程,hardware course,音标,读音,翻译,英文例句,英语词典...
  17. 浅析信号与系统1(指数信号与正弦信号)
  18. 道一HTTP测试工具功能升级
  19. CCleaner解决的三个问题
  20. 如何减少上下文切换?

热门文章

  1. 【转】slideUp() 和slideDown() 如何解决反复抖动的问题
  2. 3ds max基础材质初学者必读(27)——使用Arch Design材质
  3. AV1编码器优化技术
  4. 你不得不看的“互联网+企业购”大趴攻略
  5. 桌面快捷方式异常——左下角附有问号怎么办
  6. 世人皆苦,唯有自渡的句子,句句触动灵魂!
  7. 应用程序初始化(0xc0000034)失败
  8. vitrualbox虚拟机64位安装报错解决
  9. TruckSim Quick Start Guide(TruckSim快速入门)
  10. Maven下载sources时报错java.lang.RuntimeException: Cannot reconnect