JVM(11)——详解CMS垃圾回收器

CMS (Concurrent Mark-Sweep) 垃圾回收器。它是 JDK 1.4 后期引入,并在 JDK 5 - JDK 8 期间广泛使用的一种以低停顿时间 (Low Pause Time) 为主要目标的老年代垃圾回收器。它是 G1 出现之前解决 Full GC 长停顿问题的主要方案。

一、CMS 的设计目标与定位

  1. 核心目标:最小化应用停顿时间 (STW - Stop-The-World)。

    • 特别关注老年代垃圾回收引起的停顿。

    • 旨在避免传统 Serial Old GC(标记-整理)导致的长时间、全局性的停顿,这对交互式应用(如 Web 服务器、GUI 应用)至关重要。

  2. 实现方式:并发 (Concurrent) 收集。

    • 将垃圾回收中最耗时的标记 (Marking) 和清除 (Sweeping) 阶段,尽可能与应用线程并发执行,从而大大减少需要 STW 的时间。

  3. 算法:标记-清除 (Mark-Sweep)。

    • 标记: 找出所有存活的对象。

    • 清除: 回收未被标记(即死亡)的对象占用的空间。

    • 注意: 它不进行压缩 (Compaction),这是它产生内存碎片的主要原因。

  4. 分代收集: CMS 主要管理老年代 (Old Generation)。它通常与一个年轻代收集器搭配使用,如 ParNew(并行复制算法,Serial 的多线程版本)或 Serial

  5. 定位: 在 G1 成熟之前,CMS 是追求低延迟老年代回收的首选方案,尤其适用于中小型堆(如 4GB - 8GB)、CPU 资源相对充足且能容忍一些内存碎片和额外 CPU 开销的应用。

二、CMS 的工作阶段 (Phases)

CMS 的垃圾回收周期(针对老年代)由多个阶段组成,其中只有部分阶段需要 STW:

  1. 初始标记 (Initial Mark - STW)

    • 目标: 标记从 GC Roots 直接可达 的老年代对象(速度很快)。

    • STW 原因: 需要暂停应用线程以确保在一致性的快照下快速扫描 GC Roots(线程栈、静态变量、JNI 引用等)。

    • 优化: 这个阶段通常借道一次 Young GC(Minor GC)来完成。因为 Young GC 本身就需要 STW 并扫描 GC Roots,CMS 可以“搭便车”标记那些从根集直接引用的老年代对象,避免了额外的完整根扫描停顿。所以 CMS 触发的时机往往紧跟在一次 Young GC 之后。

  2. 并发标记 (Concurrent Mark - Concurrent)

    • 目标: 从“初始标记”阶段标记的直接可达对象开始,遍历整个老年代对象图,标记所有间接可达的存活对象。

    • 并发性: 这是 CMS 减少停顿的关键!这个阶段与应用线程同时运行。应用线程可以继续创建新对象、更新引用关系。

    • 挑战 - 浮动垃圾 (Floating Garbage): 因为在标记过程中应用线程还在运行,可能会产生新的垃圾对象(标记阶段结束后才成为垃圾)或者使已标记的对象变成垃圾。同时,应用线程修改对象引用关系可能导致“漏标”或“多标”问题。CMS 使用 增量更新 (Incremental Update) 算法来解决对象引用变化的问题(与 G1 的 SATB 不同)。

    • 挑战 - 耗时: 遍历整个老年代对象图,即使并发,也可能花费较长时间,特别是大堆。

  3. 重新标记 (Remark - STW)

    • 目标: 修正“并发标记”阶段因应用线程继续运行而导致的标记变动,确保所有在并发标记期间存活的对象都被正确标记。处理在并发阶段新晋升到老年代的对象(如果搭配 ParNew,晋升发生在 Young GC 的 STW 阶段,相对容易处理)。

    • STW 原因: 为了获得一个最终准确的存活对象视图,需要在一个确定的点上暂停所有应用线程。

    • 优化: 这个阶段通常比“初始标记”长,但比“并发标记”短得多。JVM 会使用多线程并行处理来加速。可以启用 -XX:+CMSScavengeBeforeRemark 参数,在重新标记前强制触发一次 Young GC,清理掉年轻代的垃圾,减少需要扫描的年轻代对象数量(年轻代对象也可能引用老年代对象),从而缩短 STW 时间。

  4. 并发清除 (Concurrent Sweep - Concurrent)

    • 目标: 回收那些在标记阶段被确定为死亡对象所占用的内存空间。

    • 并发性: 这个阶段也与应用线程同时运行。应用线程可以继续分配新对象(在空闲列表管理的内存区域)。

    • 算法: 使用空闲列表 (Free List) 管理回收后的空间。清除器遍历内存,将连续的死对象空间合并成空闲块,记录在空闲列表中,供后续分配使用。

    • 结果: 回收了垃圾内存,但不进行内存整理压缩。这导致了内存碎片问题。

  5. 并发重置 (Concurrent Reset - Concurrent)

    • 目标: 为下一次 CMS 周期重置内部数据结构(如标记位图)。

    • 并发性: 与应用线程同时运行,无停顿。

三、CMS 的核心特性与优势

  1. 低停顿时间 (Low Pause Time): 这是 CMS 最大的优势。通过将最耗时的标记和清除工作并发执行,显著减少了 STW 的时间(主要集中在初始标记和重新标记阶段),使得老年代回收对应用响应时间的影响大大降低。

  2. 并发收集 (Concurrent Collection): 真正实现了垃圾回收线程与应用线程在大部分时间并行工作。

  3. 适用于延迟敏感型应用: 在 G1 成熟之前,是 Web 服务器、交易系统等需要快速响应的应用的首选老年代回收器。

四、CMS 的缺点与挑战

  1. 内存碎片 (Memory Fragmentation):

    • 根本原因: 使用标记-清除算法且不压缩内存。长时间运行后,老年代会由许多存活对象和大小不一、分散的空闲内存块组成。

    • 后果:

      • 分配失败: 即使老年代总的空闲空间足够,也可能因为找不到足够大的连续空间来分配一个大对象(或晋升对象),从而触发 Full GC (Serial Old GC)

      • Full GC 时间长: Serial Old GC 是单线程的标记-整理-压缩算法,在大堆上进行压缩会导致非常长的 STW 停顿,违背了使用 CMS 的初衷。

    • 缓解措施:

      • -XX:+UseCMSCompactAtFullCollection (默认 true): 在不得不进行 Full GC 时,在 Full GC 后进行内存压缩。

      • -XX:CMSFullGCsBeforeCompaction=n (默认 0): 设定在多少次不压缩的 Full GC 后,执行一次带压缩的 Full GC。0 表示每次 Full GC 都压缩(推荐)。但这仍然意味着要经历一次长时间的 Full GC。

  2. 并发模式失败 (Concurrent Mode Failure):

    • 触发条件:

      • 老年代空间不足: 在 CMS 并发周期(标记和清除)完成之前,老年代空间就被填满了。这通常发生在:

        • 老年代分配/晋升速率过快,超过 CMS 回收速度。

        • 浮动垃圾过多,占用了本应回收的空间。

        • 并发周期启动太晚(-XX:CMSInitiatingOccupancyFraction 设置过高)。

      • 晋升失败 (Promotion Failed): Young GC 后,存活对象需要晋升到老年代,但老年代没有足够的连续空间容纳它们(即使总空间可能够,但碎片导致)。

    • 后果: JVM 会立即中断 CMS 并发周期,并触发一次 Full GC (Serial Old GC)。这会导致一个计划外的、长时间的 STW 停顿。

    • 预防措施:

      • 合理设置 -XX:CMSInitiatingOccupancyFraction降低老年代空间占用阈值(如从默认 68% 设到 50% 或更低),尽早启动 CMS 并发周期,给并发回收留出足够的时间窗口和空间裕度。

      • 必须配合 -XX:+UseCMSInitiatingOccupancyOnly 使用:确保 JVM 根据 CMSInitiatingOccupancyFraction 的值启动 CMS,而不是自行“自适应”调整(可能导致启动过晚)。

      • 增加堆大小或老年代比例 (-Xmx-Xms-XX:NewRatio)。

      • 优化应用,减少对象创建和晋升速率、减小对象大小、避免过大的对象。

      • 增加 CMS 回收线程数 (-XX:ConcGCThreads / -XX:ParallelCMSThreads, 后者在较新版本已废弃,推荐用 ConcGCThreads)。

  3. 对 CPU 资源敏感 (CPU Sensitive):

    • 原因: 并发标记和并发清除阶段需要与应用线程争抢 CPU 资源。

    • 后果:

      • 在 CPU 资源紧张(如 CPU 核数少、负载高)的情况下,并发回收线程会拖慢应用线程的执行速度,导致应用吞吐量下降

      • 并发阶段本身可能因为 CPU 争抢而执行得更慢,增加了并发模式失败的风险。

    • 建议: CMS 更适合 CPU 资源相对富余(核数较多或负载不高)的机器。

  4. 浮动垃圾 (Floating Garbage): 如前所述,并发过程中产生的垃圾只能在下一次 GC 回收。需要预留足够空间容纳这些浮动垃圾。

  5. 元空间/永久代触发 Full GC: CMS 不管理元空间 (Metaspace, JDK 8+) 或永久代 (PermGen, JDK 7-)。如果元空间/永久代空间不足,会触发 Full GC。

  6. JDK 9+ 中已弃用 (Deprecated),JDK 14+ 中已移除 (Removed):

    • 弃用原因: G1 作为更现代、设计更优的回收器(同样追求低延迟,且解决了碎片问题)已成为默认选择。CMS 的维护成本高,且其架构难以适应更新的 Java 特性和硬件发展(如非常大的堆)。

    • 后果: 在新版本 JDK (>=14) 中无法再使用 CMS。仍在使用的应用应尽快迁移到 G1 或其他回收器(如 ZGC, Shenandoah)。

五、关键配置参数

  • 启用 CMS:

    • -XX:+UseConcMarkSweepGC (JDK 8 及之前)

  • 设置年轻代收集器 (通常自动选择):

    • 搭配 ParNew:-XX:+UseParNewGC (通常启用 CMS 会自动启用)

  • 触发 CMS 的堆占用阈值 (最重要!):

    • -XX:CMSInitiatingOccupancyFraction=<percent> (e.g., 70): 当老年代空间占用达到此百分比时,启动 CMS 并发收集周期。建议设低一些(如 50-70)以预防并发模式失败。

  • 强制使用阈值触发 (必须配!):

    • -XX:+UseCMSInitiatingOccupancyOnly强制 JVM 只使用 CMSInitiatingOccupancyFraction 的值作为触发条件,禁用 JVM 的自适应调整。

  • 重新标记前进行 Young GC:

    • -XX:+CMSScavengeBeforeRemark: 在重新标记阶段前强制触发一次 Young GC,减少需要扫描的年轻代对象,有效缩短重新标记 STW 时间(强烈推荐启用)。

  • CMS 线程数:

    • -XX:ConcGCThreads=<n> / -XX:ParallelCMSThreads=<n> (后者较旧): 设置并发阶段(标记、清除)使用的线程数。默认为 (ParallelGCThreads + 3) / 4。可根据 CPU 核数调整。

  • Full GC 后压缩:

    • -XX:+UseCMSCompactAtFullCollection (默认 true): Full GC 后进行压缩。

    • -XX:CMSFullGCsBeforeCompaction=<n> (默认 0): 执行 n 次不压缩的 Full GC 后,执行一次带压缩的 Full GC。0 表示每次都压缩。

六、何时使用(或曾经使用)CMS?

  • 历史场景 (JDK 8 及之前):

    • 应用对老年代回收停顿时间非常敏感

    • 应用运行在中小型堆(如 4GB - 8GB)上。

    • 机器有富余的 CPU 资源(核数较多,负载不高)。

    • 应用能够容忍一定程度的内存碎片或通过配置降低了 Full GC 风险。

    • 需要避免 Serial Old GC 的长停顿

  • 当前状态:

    • JDK 9+:已弃用 (Deprecated)。

    • JDK 14+:已移除 (Removed)。

    • 强烈建议所有仍在使用 CMS 的应用迁移到 G1(目前默认且成熟)或探索新一代超低延迟回收器 ZGC / Shenandoah(尤其超大堆和极致低延迟需求)。

七、总结

CMS 垃圾回收器是 JVM 垃圾回收发展史上一个重要的里程碑,它率先通过并发标记清除的方式显著降低了老年代回收的停顿时间,满足了当时众多对延迟敏感型 Java 应用的需求。其核心价值在于并发性带来的低 STW 停顿

然而,CMS 的固有缺陷也非常明显:

  1. 标记-清除算法导致内存碎片, 最终可能引发长时间的 Serial Old Full GC。

  2. 对并发模式失败 (Concurrent Mode Failure) 非常敏感, 需要精细调优(尤其是 CMSInitiatingOccupancyFraction 和 UseCMSInitiatingOccupancyOnly)。

  3. 并发阶段占用 CPU 资源,影响吞吐量。

  4. 无法管理元空间/永久代。

  5. 已被现代 JDK (>=14) 彻底移除。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/89011.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/89011.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Java和iText库填充PDF表单域的完整指南

PDF表单是企业和机构常用的数据收集工具&#xff0c;而通过编程方式自动填充PDF表单可以大大提高工作效率。本文将详细介绍如何使用Java和iText库来实现PDF表单的自动化填充。 为什么选择iText库&#xff1f; iText是一个强大的PDF操作库&#xff0c;具有以下优势&#xff1a…

跟着AI学习C#之项目实践Day6

&#x1f4c5; Day 6&#xff1a;实现文章搜索功能&#xff08;Search System&#xff09; ✅ 今日目标&#xff1a; 实现按 标题、内容、作者 搜索文章使用 LINQ 构建动态查询条件添加搜索框 UI 界面可选&#xff1a;使用全文搜索优化&#xff08;如 SQL Server 全文索引&am…

Learning to Prompt for Continual Learning

Abstract 持续学习背后的主流范式是使模型参数适应非平稳数据分布&#xff0c;其中灾难性遗忘是核心挑战。典型方法依赖于排练缓冲区或测试时已知的任务标识来检索已学知识并解决遗忘问题&#xff0c;而这项工作提出了一种持续学习的新范式&#xff0c;旨在训练一个更简洁的记…

【论文阅读笔记】知网SCI——基于主成分分析的空间外差干涉数据校正研究

论文词条选择 —— 知网 【SCI】【数据分析】 题目&#xff1a;基于主成分分析的空间外差干涉数据校正研究 原文摘要&#xff1a; 空间外差光谱技术(SHS)是一种新型的高光谱遥感探测技术&#xff0c;被广泛应用于大气观测、天文遥感、物质识别等领域。通过空间外差光谱仪获取…

如何用VS Code、Sublime Text开发51单片机

文章目录 一、前置工作二、VS Code2.1 Code Runner配置2.2 编译快捷键 三、Sublime Text3.1 Build System创建3.2 编译快捷键 四、使用STC-ISP下载代码到单片机 使用VS Code开发51单片机的好处自不必多说&#xff0c;直接进入正题。本博客的目标是让你能够使用VS Code或者Subli…

信息抽取数据集全景分析:分类体系、技术演进与挑战_DEEPSEEK

信息抽取数据集全景分析&#xff1a;分类体系、技术演进与挑战 摘要 信息抽取&#xff08;IE&#xff09;作为自然语言处理的核心任务&#xff0c;是构建知识图谱、支持智能问答等应用的基础。近年来&#xff0c;随着深度学习技术的发展和大规模预训练模型的兴起&#xff0c;…

利用 Python 脚本批量查找并删除指定 IP 的 AWS Lightsail 实例

在 AWS Lightsail 管理中&#xff0c;随着实例数量的增多&#xff0c;我们常常会遇到这样一个问题&#xff1a; “我知道某个公网 IP 地址&#xff0c;但不知道它关联的是哪台实例。” 或者&#xff1a; “我有一批老旧的实例只知道 IP&#xff0c;需要一键定位并选择删除。…

CompletableFuture 深度解析

本文将探讨 Java 8 引入的 CompletableFuture&#xff0c;一个在异步编程中实现非阻塞、可组合操作的强大工具。我们将从 CompletableFuture 的基本概念、与传统 Future 的区别、核心 API 用法&#xff0c;到复杂的链式调用、组合操作以及异常处理进行全面解析&#xff0c;并通…

给自己网站增加一个免费的AI助手,纯HTML

助手效果图 看完这篇文章&#xff0c;你将免费拥有你自己的Ai助手&#xff0c;全程干货&#xff0c;先到先得 获取免费的AI大模型接口 访问这个地址 生成key https://openrouter.ai/mistralai/mistral-small-3.2-24b-instruct:free/api 或者调用其他的免费大模型&#xff0c;这…

ASProxy64.dll导致jetbrains家的IDE都无法打开。

在Windows11中,无法打开jetbrains的IDE的软件,经过排查,发现与ASProxy64.dll有关。 E:\idea\IntelliJ IDEA 2024.1.7\bin>idea.bat CompileCommand: exclude com/intellij/openapi/vfs/impl/FilePartNodeRoot.trieDescend bool exclude = true # # A fatal error has bee…

springboot+Vue逍遥大药房管理系统

概述 基于springbootVue开发的逍遥大药房管理系统。该系统功能完善&#xff0c;既包含强大的后台管理模块&#xff0c;又具备用户友好的前台展示界面。 主要内容 一、后台管理系统功能 ​​核心管理模块​​&#xff1a; 用户管理&#xff1a;管理员与普通用户权限分级药品分…

探索阿里云智能媒体管理IMM:解锁媒体处理新境界

一、引言&#xff1a;开启智能媒体管理新时代 在数字化浪潮的席卷下&#xff0c;媒体行业正经历着前所未有的变革。从传统媒体到新媒体的转型&#xff0c;从内容生产到传播分发&#xff0c;每一个环节都在寻求更高效、更智能的解决方案。而云计算&#xff0c;作为推动这一变革…

[附源码+数据库+毕业论文]基于Spring+MyBatis+MySQL+Maven+jsp实现的新生报道管理系统,推荐!

摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了新生报道管理系统的开发全过程。通过分析高校新生入学报到信息管理的不足&#xff0c;创建了一个计算机管理高校新生入学报到信息的方案。文章介绍了新生报道管…

给定一个整型矩阵map,求最大的矩形区域为1的数量

题目: 给定一个整型矩阵map,其中的值只有0和1两种,求其中全是1的 所有矩形区域中,最大的矩形区域为1的数量。 例如: 1 1 1 0 其中,最大的矩形区域有3个1,所以返回3。 再如: 1 0 1 1 1 1 1 1 1 1 1 0 其中,最大的矩形区域有6个1,所以返回6。 解题思…

第8章-财务数据

get_fund # 查看股票代码000001.XSHE在2022年9月1日的总市值 q query( valuation ).filter( valuation.code 000001.XSHE ) df get_fundamentals(q, 2022-09-01) print(df[market_cap][0]) # 获取第一行的market_cap值 这段代码看起来是用于查询股票在特定日期的总…

SQL关键字三分钟入门:ROW_NUMBER() —— 窗口函数为每一行编号

在进行数据分析时&#xff0c;我们常常需要为查询结果集中的每条记录生成一个唯一的序号或行号。例如&#xff1a; 为每位员工按照入职时间排序并编号&#xff1b;按照订单金额对订单进行排序&#xff0c;并给每个订单分配一个顺序编号&#xff1b;在分组数据内为每条记录编号…

微信小程序如何实现通过邮箱验证修改密码功能

基于腾讯云开发&#xff08;Tencent Cloud Base&#xff09;实现小程序邮箱验证找回密码功能的完整逻辑说明及关键代码实现。结合安全性和开发效率&#xff0c;方案采用 ​​云函数 小程序前端​​ 的架构&#xff0c;使用 ​​Nodemailer​​ 发送邮件。Nodemailer 是一个专为…

C# VB.NET中Tuple轻量级数据结构和固定长度数组

C# VB.NET取字符串中全角字符数量和半角字符数量-CSDN博客 https://blog.csdn.net/xiaoyao961/article/details/148871910 在VB.NET中&#xff0c;使用Tuple和固定长度数组在性能上有细微差异&#xff0c;以下是详细分析&#xff1a; 性能对比测试 通过测试 100 万次调用&am…

建筑物年代预测与空间异质性分析解决方案

建筑物年代预测与空间异质性分析解决方案 1. 问题分析与创新点设计 核心任务:预测建筑物建造年代,并分析空间异质性对预测的影响 创新点设计: 空间权重矩阵集成:构建空间邻接矩阵量化地理邻近效应多尺度特征提取:融合建筑物微观特征与街区宏观特征异质性分区建模:基于…

FOUPK3system5XOS

Foupk3systemX5OS系统19.60内测版&#xff08;X9&#xff09;2023年4月16日正式发布 1.0Foupk3systemX5OS系统19.60&#xff08;X9&#xff09;2024年10月6日发布 Foupk3systemX5OS系统19.60增强版&#xff08;X9X5&#xff09;2024年10月6日发布Foupk3systemX5OS系统19.60正…