欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 锐评 > 【gopher的java学习笔记】Concurrent Mark-Sweep GC过程详细解析

【gopher的java学习笔记】Concurrent Mark-Sweep GC过程详细解析

2025/11/7 1:28:42 来源:https://blog.csdn.net/u013135921/article/details/144976620  浏览:    关键词:【gopher的java学习笔记】Concurrent Mark-Sweep GC过程详细解析
引言

Concurrent Mark-Sweep(CMS)GC是Java虚拟机(JVM)中一种以减少停顿时间为目标的垃圾收集器,特别适用于需要低延迟的服务场景,如Web应用、实时系统等。本文将详细解析CMS GC的工作过程,包括其各个阶段的具体步骤和特点。

1. CMS GC概述

CMS GC是HotSpot虚拟机中首款真正意义上的并发收集器,它首次实现了垃圾收集线程与用户线程(基本上)同时工作。CMS GC主要针对老年代进行垃圾回收,可以与ParNew或Serial等新生代收集器配合使用。

2. CMS GC工作流程

CMS GC的工作流程可以细分为以下几个阶段:

2.1 初始标记(Initial Mark)
  • 阶段描述:初始标记阶段会暂停所有应用线程(Stop-The-World, STW),从GC Roots开始,标记所有直接可达的对象。
  • 特点:此阶段耗时非常短,因为只标记直接与GC Roots相连的对象。
  • 日志示例
    [GC (CMS Initial Mark) [1 CMS-initial-mark: 3714K(6848K)] 4760K(9920K), 0.0004679 secs]
    
2.2 并发标记(Concurrent Mark)
  • 阶段描述:在初始标记完成后,CMS GC开始并发地标记剩余的对象。从GC Roots开始,遍历整个对象图,标记所有可达的对象。
  • 特点:此阶段与应用程序线程并发执行,不会暂停应用线程,因此用户几乎感觉不到停顿。
  • 可能问题:由于应用程序线程仍在运行,可能会产生新的对象或对象引用关系发生变化,导致标记不准确。
2.3 并发预清理(Concurrent Preclean,可选)
  • 阶段描述:并发预清理阶段是为了减少重新标记阶段的工作量。它查找并发标记阶段中新进入老年代的对象,包括晋升到老年代和直接在老年代分配的对象。
  • 特点:此阶段也是并发的,与应用程序线程同时执行。
  • 参数控制:通过-XX:CMSPrecleaningEnabled参数可以启用或禁用此阶段。
2.4 重新标记(Remark)
  • 阶段描述:重新标记阶段会暂停所有应用线程(STW),处理并发标记阶段因应用程序线程运行而产生标记变动的对象。
  • 特点:此阶段会修正标记记录,确保所有存活对象都被正确标记。耗时比初始标记阶段稍长,但远短于并发标记阶段。
  • 日志示例
    [GC (CMS Final Remark) [YG occupancy: 1046 K (3072 K)][Rescan (parallel) , 0.0001200 secs] ... [1 CMS-remark: 3714K(6848K)] 4760K(9920K), 0.0011706 secs]
    
2.5 并发清除(Concurrent Sweep)
  • 阶段描述:在重新标记完成后,CMS GC开始并发地清除未被标记的对象,释放内存空间。
  • 特点:此阶段与应用程序线程并发执行,不会暂停应用线程。
  • 日志示例
    [CMS-concurrent-sweep-start] [CMS-concurrent-sweep: 0.001/0.001 secs]
    
2.6 并发重置(Concurrent Reset)
  • 阶段描述:并发重置阶段重置CMS GC的内部数据结构,为下一次垃圾收集做准备。
  • 特点:此阶段也是并发的,与应用程序线程同时执行。
  • 日志示例
    [CMS-concurrent-reset-start] [CMS-concurrent-reset: 0.000/0.000 secs]
    
3. CMS GC的优缺点

优点

  • 并发收集:大部分垃圾收集工作与用户线程并发执行,大大减少了应用程序的停顿时间。
  • 低停顿:通过并发标记和清除,CMS GC能够尽量缩短垃圾收集对应用程序的影响,适合对延迟敏感的应用场景。

缺点

  • 内存碎片:CMS GC使用标记-清除算法,会产生大量不连续的内存碎片,可能导致大对象无法分配,从而触发Full GC。
  • 对CPU资源敏感:并发阶段会占用一部分CPU资源,导致应用程序的总吞吐量降低。
  • 无法处理浮动垃圾:在并发标记和清除阶段,应用程序可能会产生新的垃圾对象,这些垃圾对象只能在下一次GC时回收,称为浮动垃圾。
  • 并发模式失败:如果CMS GC无法在老年代满之前完成垃圾回收,会导致并发模式失败,此时会退化为使用Serial Old收集器进行垃圾回收,产生较长的停顿时间。
4. CMS GC的配置参数

CMS GC提供了多个配置参数,用于调整其行为和性能。以下是一些常用的配置参数:

  • -XX:+UseConcMarkSweepGC:启用CMS GC。
  • -XX:CMSInitiatingOccupancyFraction=N:设置老年代内存使用达到该百分比时触发CMS GC。默认值为68%,可以根据应用需求进行调整。
  • -XX:+UseCMSCompactAtFullCollection:在Full GC后进行内存碎片整理。默认值为开启,但会增加停顿时间。
  • -XX:CMSFullGCsBeforeCompaction=N:设置多少次不压缩的Full GC后进行一次内存整理。默认值为0,表示每次Full GC都进行整理。
  • -XX:+CMSScavengeBeforeRemark:在重新标记前强制进行一次Minor GC,以减少因新生代对象过多而导致的长时间重新标记阶段。
5. CMS GC的调优策略

为了优化CMS GC的性能,可以采取以下调优策略:

  • 调整触发百分比:根据应用程序的内存使用情况和垃圾产生速度,调整-XX:CMSInitiatingOccupancyFraction参数,以平衡垃圾收集的频率和停顿时间。
  • 启用内存整理:在内存碎片问题严重时,可以启用-XX:+UseCMSCompactAtFullCollection参数,在Full GC后进行内存碎片整理,但需要注意这会增加停顿时间。
  • 控制Full GC次数:通过调整-XX:CMSFullGCsBeforeCompaction参数,控制Full GC后进行内存整理的频率,以减少对应用程序性能的影响。
  • 优化代码:通过优化应用程序的代码,减少对象的创建和销毁频率,从而降低垃圾收集的负担。
6. 结论

CMS GC是一种以减少停顿时间为目标的垃圾收集器,特别适用于需要低延迟的服务场景。通过详细解析其工作流程和各个阶段的特点,我们可以更好地理解CMS GC的工作原理。然而,它也存在内存碎片、对CPU资源敏感、无法处理浮动垃圾等缺点。在实际应用中,需要根据应用程序的特点和需求选择合适的垃圾收集器,并通过合理的配置和调优策略来优化其性能。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词