JVM 并发 GC - 三色标记

垃圾收集就意味着需要进行可达性算法,但是在执行可达性算法时,当前的 JVM 内部需要保持一个禁止的状态,也就是其他的用户线程不允许进行操作,所有的用户线程需要等到垃圾收集结束后才能开始继续执行,这意味着用户的体验感可能会非常地差:用户可能正在访问某个页面时,JVM 突然开始垃圾回收,如果当前 Java 堆内对象较少,那用户可能会怀疑是自己的网络原因,但是如果已经达到了十分庞大的对象量,用户就会看着加载页面转啊转,甚至弹出页面暂时无法访问。这个时候并发处理就十分重要了。

并发的可达性分析算法 - 三色标记

在三色标记算法中,对象会被标记为三种颜色之一:

  • 白色:表示对象尚未被访问,可能是垃圾。
  • 灰色:表示对象已被访问,但其引用的对象尚未全部访问。
  • 黑色:表示对象及其所有引用的对象都已访问。

但是如果是在并发地进行并发的可达性算法时,用户线程突然对某个将要被删除、并且已经被标记了的对象进行了操作,我们假设所有对象都没有重写 finalize (毕竟 Java 官方不推荐使用),那么这个对象可能刚好被引用,但是下一秒就又被删除了,这样子导致错误。

https://shipilev.net/talks/javazone-Sep2018-shenandoah.pdf

Wilson 在 1994 年在理论上证明了,当且仅当以下两种条件都满足时,会产生"对象消失"问题

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

即:当前对象还未被扫描,当前对象被已经被扫描过并且标记了不会有其他引用对象的对象引用

因此,想要解决并发扫描时对象消失问题,只需要破坏这两种条件的其中一种即可

  • 增量更新
  • 原始快照

增量更新

增量更新破坏的是 "赋值器插入了一条或多条从黑色对象到白色对象的引用" 条件

当对黑色对象插入新的指向白色对象的引用关系时,就将这个新插入的引用记录下来,在并发扫描后,再将这些记录过的引用关系中的黑色对象为根,再重新扫描一次,可以简单理解为:只要黑色对象插入新的指向白色对象的引用,黑色对象就会变成灰色对象

原始快照

当灰色对象要删除指向白色对象的引用关系时,就将这个要删除的引用记录下来,在并发扫描结束之后再将这些记录过的引用关系中的灰色对象为根,重新扫描一次。可以简单理解成:无论引用关系删除与否都会按照刚刚开始扫描的那一刻的图像快照来进行搜索

简单来说,增量更新和原始快照都在一次可达性算法过后对更新过的节点进行扫描以达到不会产生"对象消失"的目的

相关推荐
考研保研资料分享6 小时前
2022双非保研华科热能工程:三校考核、传热题与报名复盘
面试
wuminyu10 小时前
JVM规范学习总结:解释器与JIT编译器如何处理JVM字节码
java·linux·c语言·jvm·c++
骑着蜗牛撵大象32711 小时前
大模型 Agent 的沙箱护栏:gVisor 隔离、出口白名单与审计闭环
java·开发语言·jvm·安全·agent沙箱·gvisor·microvm
weixin_3077791312 小时前
RAG 面试陷阱——混合检索并非无条件优越:一个条件反转实验
人工智能·python·面试·职场和发展
nice_lcj52013 小时前
深入理解 Java 反射:从 Class 对象到方法调用(含性能实测 + 迷你 IOC 实战 + 面试考点)
java·开发语言·后端·面试
tryxr14 小时前
JVM 垃圾回收机制
java·jvm·gc·垃圾回收
D e re k ZH16 小时前
C++ 并发、未定义行为与工程化难点(No 3)
数据结构·c++·算法·面试
香蕉大香蕉(06敬畏市场)20 小时前
MySQL 单点详解(08)
java·数据库·mysql·面试·八股
Thanks_ks21 小时前
常见 HTTP 状态码的坑:301/302、401/403、500/502 之间差的那一个词
计算机网络·nginx·http·面试·状态码·后端开发·浏览器缓存
怕浪猫21 小时前
Super-agent 在各大模型厂商的应用情况
算法·面试·github