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

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

简单概括三色标记算法

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

总结

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

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

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

多标

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

漏标

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

相关推荐
你想考研啊3 分钟前
linux安装jdk和tomcat和并自启动
java·linux·tomcat
悟能不能悟2 小时前
java的java.sql.Date和java.util.Date的区别,应该怎么使用
java·开发语言
高山上有一只小老虎3 小时前
java 正则表达式大全
java·正则表达式
_院长大人_4 小时前
设计模式-工厂模式
java·开发语言·设计模式
凌波粒4 小时前
MyBatis完整教程IDEA版(2)--ResultMap/注解/一对多/多对一/lombok/log4j
java·intellij-idea·mybatis
蓝-萧4 小时前
【玩转全栈】----Django基本配置和介绍
java·后端
priority_key4 小时前
排序算法:堆排序、快速排序、归并排序
java·后端·算法·排序算法·归并排序·堆排序·快速排序
汤姆yu6 小时前
基于SpringBoot的动漫周边商场系统的设计与开发
java·spring boot·后端
皮皮林5516 小时前
快速解决 Maven 版本冲突指南 !
java·maven
灰小猿6 小时前
Spring前后端分离项目时间格式转换问题全局配置解决
java·前端·后端·spring·spring cloud