当前主流编程语言的垃圾收集器基本上都是依靠可达性分析算法来判定对象是否存活的,可达性分析算法理论上要求全过程都基于一个能保障一致性的快照中才能够进行分析,这意味着必须全程冻结用户线程的运行。

  • 在根节点枚举这个步骤中,由于 GC Roots 相比起整个 Java 堆中全部的对象毕竟还算是极少数,且在各种优化技巧(如 OopMap)的加持下,它带来的停顿已经是非常短暂且相对固定(不随堆容量而增长) 的了。
  • 可从 GC Roots 再继续往下遍历对象图,这一步骤的停顿时间就必定会与 Java 堆容量直接成正比例关系了:堆越大,存储的对象越多,对象图结构越复杂,要标记更多对象而产生的停顿时间自然就更长。

要知道包含 “标记” 阶段是所有追踪式垃圾收集算法的共同特征,如果这个阶段会随着堆变大而等比例增加停顿时间,其影响就会波及几乎所有的垃圾收集器,同理可知,如果能够削减这部分停顿时间的话,那收益也将会是系统性的。

想解决或者降低用户线程的停顿,就要先搞清楚为什么必须在一个能保障一致性的快照上才能进行对象图的遍历?为了能解释清楚这个问题,我们引入三色标记(Tri-color Marking)作为工具来辅助推导,把遍历对象图过程中遇到的对象,按照 “是否访问过” 这个条件标记成以下三种颜色:

  • 白色:表示对象尚未被垃圾收集器访问过。显然在可达性分析刚刚开始的阶段,所有的对象都是白色的,若在分析结束的阶段,仍然是白色的对象,即代表不可达。
  • 黑色:表示对象已经被垃圾收集器访问过,且这个对象的所有引用都已经扫描过。黑色的对象代表已经扫描过,它是安全存活的,如果有其他对象引用指向了黑色对象,无须重新扫描一遍。黑色对象不可能直接(不经过灰色对象) 指向某个白色对象。
  • 灰色:表示对象已经被垃圾收集器访问过,但这个对象上至少存在一个引用还没有被扫描过。

关于可达性分析的扫描过程,可以发挥一下想象力,把它看作对象图上一股以灰色为波峰的波纹从黑向白推进的过程。如果用户线程此时是冻结的,只有收集器线程在工作,那不会有任何问题。但如果用户线程与收集器是并发工作呢?收集器在对象图上标记颜色,同时用户线程在修改引用关系(即修改对象图的结构),这样可能出现两种后果。

  • 一种是把原本消亡的对象错误标记为存活(即原本应该是白色的对象被误标为黑色),这不是好事,但其实这种情况是可以容忍的,只不过产生了一点逃过本次收集的浮动垃圾而已,下次收集清理掉就好。
  • 另一种是把原本存活的对象错误标记为已消亡(即原本应该是黑色的对象被误标为白色),这就是非常致命的后果了,程序肯定会因此发生错误,下图演示了这样的致命错误具体是如何产生的。

Wilson 于 1994 年在理论上证明了,当且仅当以下两个条件同时满足时,会产生 “对象消失” 的问题,即原本应该是黑色的对象被误标为白色:

  • 赋值器插入了一条或多条从黑色对象到白色对象的新引用;
  • 赋值器删除了全部从灰色对象到该白色对象的直接或间接引用。

因此,我们要解决并发扫描时的对象消失问题,只需破坏这两个条件的任意一个即可。由此分别产生了两种解决方案:增量更新(Incremental Update)和原始快照(Snapshot At The Beginning,SATB)。

  • 增量更新要破坏的是第一个条件,当要插入黑色对象指向白色对象的引用关系时,就将这个新插入的引用记录下来, 等并发扫描结束之后,再将这些记录过的引用关系中的黑色对象为根,重新扫描一次。这可以简化理解为,黑色对象一旦新插入了指向白色对象的引用之后,它就变回灰色对象了。
  • 原始快照要破坏的是第二个条件,当要删除灰色对象指向白色对象的引用关系时,就将这个要删除的引用记录下来, 等并发扫描结束之后,再将这些记录过的引用关系中的灰色对象为根,重新扫描一次。这可以简化理解为,无论引用关系删除与否,都会按照刚刚开始扫描那一刻的对象图快照来进行搜索。

以上无论是对引用关系记录的插入还是删除,虚拟机的记录操作都是通过写屏障实现的。

在 HotSpot 虚拟机中,增量更新和原始快照这两种解决方案都有实际应用,譬如,CMS 是基于增量更新来做并发标记的,G1、Shenandoah 则是用原始快照来实现。

参考资料

《深入理解Java虚拟机》第 3 章:垃圾收集器与内存分配策略 3.4.6 并发的可达性分析

JVM:并发的可达性分析相关推荐

  1. jvm根节点枚举、安全点、安全区域、记忆集、卡表、写屏障、并发的可达性分析

    讲具体的实现之前,先说说几个和这些垃圾回收器息息相关的一些知识点,可以有一个更好的理解 1.根节点枚举 也就是可达性分析算法从GC Roots集合中找引用链的过程,可作为GC Roots的节点主要在全 ...

  2. 面试官:你说你熟悉jvm?那你讲一下并发的可达性分析

    上面这张图是我还是北漂的时候,在鼓楼附近的胡同里面拍的. 那天刚刚下完雨,路过这个地方的时候,一瞬间就被这五颜六色的门板和自行车给吸引了,于是拍下了这张图片.看到这张图片的时候我就很开心,多鲜活.多舒 ...

  3. 引用计数器法 可达性分析算法_面试官:你说你熟悉jvm?那你讲一下并发的可达性分析...

    持续输出原创文章,点击蓝字关注我吧 上面这张图是我还是北漂的时候,在鼓楼附近的胡同里面拍的. 那天刚刚下完雨,路过这个地方的时候,一瞬间就被这五颜六色的门板和自行车给吸引了,于是拍下了这张图片.看到这 ...

  4. 面试篇之JVM(GC 可达性分析 回收算法 卡表 G1)

    面试篇之JVM 面试篇之JVM GC 对象存活判断 分代回收理论 常见回收算法 HotSpot实现细节 记忆集与卡表 读写屏障 回收器 并发标记 G1 面试篇之JVM GC 美团 1.JVM怎么判断一 ...

  5. JVM(3)之垃圾回收(GC垃圾收集器+垃圾回收算法+安全点+记忆集与卡表+并发可达性分析......)

    <深入理解java虚拟机>+宋红康老师+阳哥大厂面试题2总结整理 一.堆的结构组成 堆位于运行时数据区中是线程共享的.一个进程对应一个jvm实例.一个jvm实例对应一个运行时数据区.一个运 ...

  6. JVM学习 谁是垃圾?判断对象是否能被垃圾回收 可达性分析 四大引用

    系统性学习JVM请点击JVM学习目录 为什么要垃圾回收 为什么要进行垃圾回收?做任何事之前我们都要搞清做这件事的原因.当我们在运行java项目时,如果项目比较大,它会实例化很多很多对象,多到我们的内存 ...

  7. JVM 垃圾回收算法 -可达性分析算法!!!高频面试!!!

    前言:学习JVM,那么不可避免的要去了解JVM相关的垃圾回收算法,本文只是讲了讲了可达性分析算法,至于标记-清除.标记-复制,标记-整理,分代收集等等算法,会在近两天的文章中陆续更新出来. 很喜欢一句 ...

  8. 深入理解JVM(三)——JVM之判断对象是否存活(引用计数算法、可达性分析算法,最终判定),Eclipse设置GC日志输出,引用

    本文转载自https://blog.csdn.net/ochangwen/article/details/51406779 本文是基于周志明的<深入理解Java虚拟机> 堆中几乎存放着Ja ...

  9. JVM中引用计数法与可达性分析

    目录 概要 如何判断对象已死? 引用计数算法 优点 缺点 举例说明 可达性分析 图例说明 GC Roots的对象包括以下几种 可达性分析回收过程 四大引用 回收方法区 方法区的垃圾收集主要回收两部分内 ...

最新文章

  1. [:zh]给机械课程设计的一封信[:] 2017-12-23
  2. python 格式化字符串_Python字符串三种格式化输出
  3. JQ 实现点击按钮显示弹窗,点击非弹窗和按钮区域隐藏弹窗
  4. mysql分页查询limit_MySQL查询语句(where,group by,having,order by,limit)
  5. 『设计模式』开发设计的七大原则,我做人还是挺有原则,那些代码呢?
  6. SecureCRT Application 已停止工作
  7. javascript中打印对象显示[object object]_js如何打印object对象
  8. 极光推送 请检查参数合法性_极光小课堂 | 极光推送在人脸识别终端管理系统中的应用...
  9. java 判断 框架类型_第10章-验证框架 --- 验证器类型
  10. Unity Shader:Waveform波形(3)-复合波
  11. 成都链安预警:My Dash Wallet在线钱包存在“关键”漏洞,用户资金面临风险
  12. 个性化品牌开始繁荣?为设计师和代工厂牵线的平台Maker's Row获得100万美元融资 | 36氪...
  13. python实现根据文件名自动分类转移至不同的文件夹
  14. 2018年SCI论文--整合GEO数据挖掘完整复现 四 :差异表达(GSE65635)
  15. 搭建自己的 CDN 的乐趣和好处
  16. C#应用程序界面开发基础——窗体控制(6)——菜单栏、工具栏和状态栏控件
  17. 数据科学 5.1 数据处理(概念)
  18. Python入门(二十三)- 文件操作1
  19. Ubuntu 14.04 smba服务器的配置——亲测方便可用
  20. 【Arduino学习】一、IO口操作

热门文章

  1. 链路追踪-SkyWalking
  2. 【渝粤题库】陕西师范大学292011 初级微观经济学 作业(高起专)
  3. 光电子学教材 马养武
  4. 《Windows 程序设计(第3版)》——导读
  5. MySQL相关面试题总结
  6. 一篇文章搞懂Java架构师的核心技能及薪资!
  7. C语言两种方法实现归并排序
  8. 均值滤波,中值滤波,最大最小值滤波
  9. 一个人生活,如何摆脱孤独提升幸福感?
  10. strstr strcmp