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

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

简单概括三色标记算法

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

总结

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

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

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

多标

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

漏标

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

相关推荐
Cc.Y9 分钟前
Java零基础入门:封装与继承 —— 从“裸奔“到“穿衣服“,从“重复造轮子“到“站在巨人肩膀上“
java·开发语言
Escalating_xu11 分钟前
【C 语言】深入理解指针(4):回调函数、qsort、void * 与泛型排序的模拟实现
java·c语言·开发语言
Shaoshing18 分钟前
雪花算法
java
w_zero_one29 分钟前
链表(4)
java·数据结构·算法
见叶之秋1 小时前
C++ 泛型世界的两块拼图:容器适配器与仿函数
java·开发语言
MayBaymax1 小时前
MQ 基础概念与架构
java·中间件·架构·java-rocketmq
Dovis(誓平步青云)1 小时前
家里设备越来越多,如何用一张空间地图控制灯光和温度![
android·java·前端·javascript·人工智能·电脑
yuniko-n2 小时前
【Java】字符串相关坑点
java·开发语言·python
Terra.K2 小时前
Spring AI day1(SSE+AI)
java·人工智能·spring·springai
斑鸠喳喳2 小时前
线程本地存储 ThreadLocal
java·后端