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

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

简单概括三色标记算法

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

总结

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

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

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

多标

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

漏标

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

相关推荐
七牛开发者4 小时前
Codex 实践系列 Vol.04:用 Goal 和 Plan 管住一个长任务
java·数据库·人工智能·github·copilot
我命由我123454 小时前
Android Drawable - gradient
android·java·java-ee·kotlin·android studio·android-studio·android runtime
淡海水5 小时前
15-07-YooAsset面试篇-Unity性能优化与内存管理
java·unity·面试·性能优化·c#·游戏引擎
snow@li5 小时前
Java:跨平台原理与JDK、JRE、JVM全景深度解析
java·开发语言·jvm
覆东流5 小时前
2.Java程序基础
java·开发语言·后端
snow@li5 小时前
SpringBoot:全套生命周期全景详解/应用级+Bean级
java·spring boot·rpc
love_muming5 小时前
二叉树操作全解析:从递归到层序遍历
java·数据结构·算法·二叉树
小的~~5 小时前
ThreadLocal 、InheritableThreadLocal 与 TransmittableThreadLocal 的进阶指南
java·开发语言
北极糊的狐6 小时前
钉钉小程序报错data.formatTime is not a function是因为 axml 模板中不能直接调用 Page 内自定义方法!
java·小程序·钉钉
·薯条大王15 小时前
经济实惠玩云服务器|一台云服务器多人共用,子账号配置教程
java·linux·运维·服务器·汇编·c++·python