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

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

简单概括三色标记算法

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

总结

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

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

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

多标

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

漏标

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

相关推荐
caihuayuan45 分钟前
PHP建立MySQL持久化连接(长连接)及mysql与mysqli扩展的区别
java·大数据·sql·spring
ITPUB-微风20 分钟前
美团MTSQL特性解析:技术深度与应用广度的完美结合
java·服务器·开发语言
WeiLai111229 分钟前
面试基础--微服务架构:如何拆分微服务、数据一致性、服务调用
java·分布式·后端·微服务·中间件·面试·架构
非 白1 小时前
【Java】单例模式
java·笔记·单例模式
IDRSolutions_CN2 小时前
如何在 PDF 文件中嵌入自定义数据
java·经验分享·pdf·软件工程·团队开发
_风中无我。2 小时前
Spring的过滤器获取请求体中JSON参数,同时解决Controller获取不到请求体参数的问题。
java·spring·json
bing_1582 小时前
Spring Boot 中为什么 需要限流、降级和熔断?
java
猿java2 小时前
很多程序员会忽略的问题:创建 MySQL索引,需要注意什么?
java·后端·mysql
ccm032 小时前
高效开发助手:深入了解Hutool工具库
java·g工具库
雪落南城2 小时前
【Maven】maven加载不到包
java·maven