一文讲解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. 使用写屏障来捕捉并发标记阶段应用线程对对象引用的更新。通过遍历这些更新的引用来修正标记状态,确保遗漏的对象不会被错误地回收;

相关推荐
程序员小假7 分钟前
我们来说说 ThreadLocal 的原理,使用场景及内存泄漏问题
java·后端
何中应9 分钟前
LinkedHashMap使用
java·后端·缓存
tryxr17 分钟前
Java 多线程标志位的使用
java·开发语言·volatile·内存可见性·标志位
talenteddriver22 分钟前
java: Java8以后hashmap扩容后根据高位确定元素新位置
java·算法·哈希算法
云泽80825 分钟前
STL容器性能探秘:stack、queue、deque的实现与CPU缓存命中率优化
java·c++·缓存
APItesterCris29 分钟前
高并发场景下的挑战:1688 商品 API 的流量控制、缓存策略与异步处理方案
大数据·开发语言·数据库·缓存
yyy(十一月限定版)31 分钟前
c语言——栈和队列
java·开发语言·数据结构
feeday32 分钟前
Python 删除重复图片 优化版
开发语言·python
本地运行没问题35 分钟前
基于Java注解、反射与动态代理:打造简易ORM框架
java
.格子衫.36 分钟前
JS原型链总结
开发语言·javascript·原型模式