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

相关推荐
不想写代码的星星9 小时前
重识 std::tuple:一个被低估的编译期异构容器
开发语言·c++
幸福巡礼9 小时前
【LangChain 1.2 实战(八)】Agent Middleware 实战 —— 动态路由、监控、安全与容错
java·安全·langchain
techdashen10 小时前
用 Rust 写生产级服务要踩多少坑——Cloudflare 把答案做成了一个开源库
开发语言·rust·开源
码界奇点10 小时前
基于Python的微信公众号爬虫系统设计与实现
开发语言·爬虫·python·毕业设计·web·源代码管理
2401_8463395610 小时前
Vue 3 中集成 Three.js 场景的完整实现指南
jvm·数据库·python
Byron__10 小时前
Java JVM核心知识点复习笔记
java·jvm·笔记
落雪寒窗-10 小时前
Python开发个人日常记录
开发语言·python
程序员小白条10 小时前
别盲目卷算法!2026 程序员\&大学生,最稳的 AI 技术进阶路线全梳理
java·网络·人工智能·网络协议·http·面试
启山智软10 小时前
【 商城系统源码:Java与PHP的区别】
java·开发语言·php
练习时长两年半的程序员小胡10 小时前
Java程序员转大模型应用开发专题(一):核心基础概念
java·开发语言·transformer·自注意力