一文讲解CMS收集器的垃圾收集过程

CMS就是Concurrent Mark Sweep

CMS使用标记-清除算法进行垃圾收集,分为4大步:

  1. 初始标记:标记所有从GC Roots直接可达的对象,这个阶段需要STW,但速度很快
  2. 并发标记:从初始标记的对象出发,遍历所有对象,标记所有可达的对象,这个阶段是并发进行的;
  3. 重新标记:完成剩余的标记工作,包括处理并发阶段遗留下来的少量变动,这个阶段通常需要短暂的STW停顿;
  4. 并发清除:清除未被标记的对象,回收他们占用的内存空间;

那么,再刚刚的过程中,你提到了重新标记,重新标记是怎么执行的?

  • 重新标记remark阶段通常会结合三色标记法来执行,确保在并发标记期间所有存活对象都被正确标记。目的是修正并发标记阶段中可能遗漏的对象引用变化;
  • 在remark阶段,垃圾收集器会停止应用线程STW,以确保在这个阶段不会有引用关系的进一步变化。这种暂停通常很短暂。remark阶段主要包括了以下操作:
    • 处理写屏障记录的引用变化:在并发标记阶段,应用程序可能会更新对象的引用(比如以一个黑色对象新增了对一个白色对象的引用),这些变化通过写屏障记录下来。在remark阶段,GC会处理这些记录,确保所有可达对象都正确地标记为灰色或黑色。
    • 扫描灰色对象:再次遍历灰色对象,处理它们的所有引用,确保引用的对象正确标记为灰色或者黑色。
    • 清理:确保所有引用关系正确处理后,灰色对象标记为黑色,白色对象保持不变。这一步完成后,所有存活对象都应当是黑色的;

刚刚提到了三色标记法,那就顺带普及下

  • 三色标记法是用于标记对象的存活状态,它将对象分为了三类:

    1. 白色:尚未访问的对象。垃圾回收结束之后,仍然为白色的对象会被认为是不可达的对象,可以回收;
    2. 灰色:已经访问到但未标记完其引用的对象。灰色对象是需要进一步处理的;
    3. 黑色:已经访问到并且其所有引用对象都已经标记过。黑色对象是完全处理过的,不需要再处理;
  • 三色标记法的工作流程是怎样的呢?

    1. 初始标记:从GC Roots开始,标记所有直接可达的对象为灰色;

    2. 并发标记:在此阶段,标记所有灰色对象引用的对象为灰色,然后将灰色对象自身标记为黑色。这个过程是并发的,和应用线程同时进行;

      此阶段的一个问题是,应用线程可能在并发标记期间修改对象的引用关系,导致一些对象的标记状态不准确;

    3. 重新标记:重新标记阶段的目标是处理并发标记阶段遗漏的引用变化。为了确保所有存活对象都被正确标记,remark需要在STW暂停期间执行;

    4. 使用写屏障来捕捉并发标记阶段应用线程对对象引用的更新。通过遍历这些更新的引用来修正标记状态,确保遗漏的对象不会被错误地回收;

相关推荐
假女吖☌2 分钟前
Maven 处理依赖冲突
java·python·maven
萧鼎4 分钟前
探索 Python 的 Optipoly 库:多变量多项式优化利器
开发语言·python
eguid_16 分钟前
WebRTC工作原理详细介绍、WebRTC信令交互过程和WebRTC流媒体传输协议介绍
java·音视频·webrtc·实时音视频
元亓亓亓19 分钟前
Java后端开发day41--IO流(一)--FileOutputStream&FileInputStream
java·开发语言
泽020224 分钟前
C++之运算符重载实例(日期类实现)
开发语言·c++
sunbyte25 分钟前
Three.js + React 实战系列 - 客户评价区细解教程 Clients 组件✨(回答式评价 + 评分星级)
开发语言·javascript·react.js
·云扬·27 分钟前
【PmHub后端篇】PmHub整合TransmittableThreadLocal (TTL)缓存用户数据
java·开发语言·缓存
marvindev36 分钟前
提bug测试专用
开发语言·javascript·bug
虚!!!看代码39 分钟前
【JVM-垃圾回收器】
jvm
androidwork1 小时前
Kotlin与Android Studio开发环境配置指南
开发语言·kotlin·android studio