当前位置: 首页 > news >正文

CMS(Concurrent Mark Sweep)垃圾回收器的具体流程

引言

CMS(Concurrent Mark Sweep)收集器是Java虚拟机中的一款并发收集器,其设计目标是最小化停顿时间,非常适合于对响应时间敏感的应用。与传统的串行或并行收集器不同,CMS能够尽可能地让垃圾收集线程与用户线程同时运行,从而减少应用程序的停顿时间。本文将详细介绍CMS收集器的工作流程。

CMS收集器的基本概念

CMS收集器采用“标记-清除”算法,在整个GC过程中尽量保持与用户线程的并发执行。它由多个阶段组成,每个阶段都有特定的任务,并且根据是否需要暂停用户线程分为两类:需要短暂暂停的阶段和完全并发的阶段。

CMS收集器的工作流程

CMS收集器的操作可以分为四个主要阶段,以及一个额外的重置阶段:

  1. 初始标记 (Initial Mark)

    • 在这个阶段,所有其他线程都会被暂停(“Stop The World”, STW),以便准确记录下直接从GC Roots可达的对象。
    • 这个过程非常快,因为它只需要扫描根节点(如栈帧中的引用、静态变量等),而不需要遍历整个对象图。
  2. 并发标记 (Concurrent Mark)

    • 此时,用户线程恢复运行,垃圾收集器开始从GC Roots出发,沿着对象之间的引用关系递归地访问并标记所有存活的对象。
    • 由于用户线程在继续工作,可能会导致已经标记过的对象状态发生变化,因此需要额外的机制来确保正确性,比如三色标记法中的增量更新或原始快照(SATB)。
  3. 重新标记 (Remark)

    • 为了修正并发标记期间因用户程序继续运行而导致的标记变动,此阶段会再次暂停所有应用线程进行快速的重新标记。
    • 主要处理的是那些在并发标记阶段新增加的引用关系或者删除了原有引用的情况,以保证不会遗漏任何存活对象。
    • 尽管重新标记阶段也会造成短暂的STW,但它的持续时间通常比初始标记稍长一些,不过远远短于并发标记的时间。
  4. 并发清理 (Concurrent Sweep)

    • 用户线程再次恢复运行,垃圾收集器则负责清理掉所有未被标记的对象。
    • 在这个过程中,如果有新创建的对象,它们会被直接标记为黑色(即存活对象),并在当前GC周期内保留下来,这有助于避免这些新对象成为浮动垃圾。
  5. 并发重置 (Concurrent Reset)

    • 最后一步是对本次GC过程中使用的标记数据进行清理和重置,为下次GC做准备。
    • 这一阶段也是完全并发的,不影响应用程序的正常运行。
CMS收集器的特点与挑战
  • 优点

    • 低停顿时间:通过并发执行减少了对用户线程的影响,使得整体停顿时间较短。
    • 高吞吐量:当CPU资源充足时,可以有效地利用多核处理器的优势,提高GC效率。
  • 缺点

    • 对CPU资源敏感:由于需要与用户线程竞争CPU资源,可能导致性能波动。
    • 浮动垃圾问题:在并发标记和清理阶段产生的新垃圾不能立即得到处理,只能等到下一次GC。
    • 空间碎片:使用标记-清除算法容易产生内存碎片,影响后续分配大对象时的成功率。
    • 并发模式失败(Concurrent Mode Failure):如果在并发标记或清理阶段结束前又触发了新的GC,可能不得不进入全局STW状态,用Serial Old收集器来完成剩余的工作。
结语

综上所述,CMS收集器是一个针对低延迟要求而优化的选择,尤其适用于Web服务器、在线交易平台等对响应速度有严格要求的场景。尽管存在一定的局限性,但是通过合理的配置参数调整,可以在很大程度上缓解这些问题,使其更好地服务于实际应用。对于开发者而言,理解CMS收集器的工作原理不仅有助于选择合适的垃圾回收策略,还能帮助更精准地调优JVM性能。

http://www.lryc.cn/news/510137.html

相关文章:

  • 【Linux】Socket编程-UDP构建自己的C++服务器
  • 磁盘结构、访问时间、调度算法
  • 详解归并排序
  • 45.在 Vue 3 中使用 OpenLayers 鼠标点击播放视频
  • 《大话Java+playWright》系列教程初级篇-初识
  • 05.HTTPS的实现原理-HTTPS的握手流程(TLS1.2)
  • 提示词工程
  • 基于python网络爬虫的搜索引擎设计
  • ip-协议
  • Git(11)之log显示支持中文
  • oneflow深度学习框架使用问题总结(Windows/Linux)
  • 论文研读:AnimateDiff—通过微调SD,用图片生成动画
  • SQLAlchemy示例(连接数据库插入表数据)
  • Springboot3国际化
  • 阿尔萨斯(JVisualVM)JVM监控工具
  • 框架专题:反射
  • 【Go】context标准库
  • LLMs之o3:《Deliberative Alignment: Reasoning Enables Safer Language Models》翻译与解读
  • git设置项目远程仓库指向github的一个仓库
  • 实战演练JDK的模块化机制
  • jdk17+springboot3项目加密部署
  • rm -rf 删除/下bin lib lib64 sbin软链接系统恢复
  • 并发与竞争
  • Java后端开发 ”Bug“ 分享——订单与优惠卷
  • Linux系统之tee命令的基本使用
  • idea 8年使用整理
  • 多个微服务 Mybatis 过程中出现了Invalid bound statement (not found)的特殊问题
  • k8s,service如何找到容器
  • 观察者模式和发布-订阅模式有什么异同?它们在哪些情况下会被使用?
  • docker compose deploy fate cluster