type
status
date
slug
summary
tags
category
icon
password
CMS(Concurrent Mark-Sweep)垃圾收集器是一种以获取最短回收停顿时间为目标的收集器,它主要用于老年代的垃圾回收。在CMS的工作过程中,"并发更新失败"(Concurrent Mode Failure)是一个常见问题,它发生在CMS运行过程中老年代空间不足以满足程序继续运行的需求时。
原因
CMS垃圾收集器包含几个阶段,其中的"并发标记"和"并发清除"阶段是在应用线程运行的同时执行的。如果在这些阶段中,应用程序对老年代空间的需求速度超过了CMS回收空间的速度,就会发生并发更新失败。此时,JVM会启动一次完全垃圾回收(Full GC),通常由Serial Old GC来执行,这会导致较长时间的应用暂停。
解决方案
- 增加堆内存大小:
- 如果系统的内存足够,增加JVM的堆内存大小可以减少发生并发更新失败的几率。
- 调整CMS的启动阈值:
- 使用
XX:CMSInitiatingOccupancyFraction
参数来调整触发CMS回收的老年代占用比率。降低这个比率可以让CMS更早启动,避免老年代被填满导致并发模式失败。
- 启用CMS的空间预留:
- 使用
XX:+UseCMSInitiatingOccupancyOnly
确保只使用CMSInitiatingOccupancyFraction
定义的阈值来触发CMS,而不是动态调整。
- 优化CMS回收周期:
- 调整
XX:CMSFullGCsBeforeCompaction
来控制执行多少次不压缩的CMS收集后,执行一次带压缩的全GC,有助于减少内存碎片。
- 减少内存分配和回收的压力:
- 优化应用程序逻辑,减少不必要的内存分配和长时间持有大对象。
- 监控和调整应用内存使用:
- 使用JVM监控工具(如JVisualVM, JMC等)监控内存使用情况,及时发现并优化内存密集型操作。
总结
CMS并发模式失败主要是由于老年代在CMS回收过程中被填满导致的,它会触发完全垃圾回收,影响应用性能。通过调整JVM参数、优化应用内存使用、监控内存使用情况,可以在一定程度上减少并发模式失败的发生,从而优化应用的性能。
- 作者:奥利弗
- 链接:https://www.aolifu.org/article/jvm_gc_cms
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。