进阶JVM面试-三色标记算法原来如此简单

首先我们的上一篇已经提到了这个三色标记算法是什么这里我们再来回顾一下CMS的流程

简单概括三色标记算法

  • 初始标记(STW):首先GC会从栈帧中的成员变量表来遍历标记GCRoot节点属性
  • 并发标记:遍历GC Root中所有属性值如果所有的属性都已经被赋值了那节点就为黑色,如果有属性还没有赋值的那就使用灰色标记
  • 重新标记(STW):扫描灰色节点的属性,查看是否有赋值操作(如果不去查看,我们在并发标记时间的赋值操作就会被漏标,对象就会被清除)
  • 并发清理:这就很简单,GC线程清理垃圾对象,程序线不会停止(主要再次触发fullgc就是使用单线程垃圾收集器,所以我们一般对堆内存做一个阈值不让放满了再清理)

总结

首先如果所有属性都已经被扫描的对象就变为黑色,如果任然有属性没有赋值没有被扫描到我们就标记黑色

在重新标记的时候就再次遍历黑色的节点,查看是否有赋值了,如果有就gc标记赋值对象并遍历赋值的对象属性,你说:"如果我取消了黑色节点的引用GC不就是不会监测到了吗?"没错是不会检测了,这种垃圾就是浮动垃圾,在下一次GC会对其进行回收

(GC标记是标记对象不是标记内存,如果发生重新赋值操作就会很乱)

多标

在我们并发标记的时候扫出了很多的黑节点,它们在下一次重新扫描是不会被扫描到的。如果我把黑节点中的属性设置为null了,本来这个属性为null应该就已经是垃圾了但是重新扫描只会扫描灰节点(避免漏标情况)。这种情况我们称这个侥幸存活下来的对象叫做浮动垃圾,它会在下一次GC被回收走

漏标

这种情况很严重如果是一个有用的对象没有被标记到,那么它就会被视做垃圾对象从而被误删除,这就是严重Bug了。所以JVM引入了三色标记法中的重新标记,防止本来null的对象在GC扫描走后重新赋值从而引发的漏标

相关推荐
兰令水1 小时前
leecodecode【反前后指针】【2026.5.31打卡-java版本】
java·开发语言
AI人工智能+电脑小能手8 小时前
【大白话说Java面试题 第87题】【Mysql篇】第17题:分布式事务的实现原理?
java·数据库·分布式·mysql·面试
来杯@Java9 小时前
图书管理系统(基于springboot+vue前后端分离的项目)计算机毕业设计java
java·spring boot·spring·vue·毕业设计·mybatis·课程设计
卷毛的技术笔记10 小时前
告别硬编码!Spring AI Alibaba 实现 AI Agent 智能工具调用(Tool Calling)
java·人工智能·后端·python·spring·ai编程
编程大师哥10 小时前
匿名函数 lambda + 高阶函数
java·python·算法
東雪木10 小时前
多线程与并发编程 专属复习笔记
java·开发语言·笔记·java面试
adrninistrat0r10 小时前
Java调用链MCP分析工具
java·python·ai编程
噜噜噜阿鲁~11 小时前
python学习笔记 | 11.3、面向对象高级编程-多重继承
java·开发语言
春生野草11 小时前
反射、Tomcat执行
java·开发语言
_日拱一卒12 小时前
LeetCode:207课程表
java·数据结构·算法·leetcode·职场和发展