在 java 中配置 -xx:+useconcmarksweepgc 需要将其作为 jvm 启动参数传入,该参数用于启用并发标记清除(cms)垃圾收集器。此配置主要适用于 jdk 8 及更早版本,因为从 jdk 9 开始 cms 已被废弃并在 jdk 14 中移除。配置时需注意它与并行 gc 或 g1 gc 的互斥性,并通常配合设置老年代大小和并发线程数等参数以优化性能。

CMS 收集器的基本配置与参数组合
启用 CMS 收集器的核心命令是添加 -XX:+UseConcMarkSweepGC 标志。为了使其有效工作,通常需要同时指定堆的大小,例如使用 -Xms 和 -Xmx。此外,CMS 允许通过 -XX:ParallelGCThreads 控制并行阶段使用的线程数,以及通过 -XX:ConcGCThreads 控制并发阶段的线程数。这些参数的组合决定了 GC 对 CPU 资源的占用情况。

-XX:+UseConcMarkSweepGC -Xms512m -Xmx512m -XX:ParallelGCThreads=4 -XX:ConcGCThreads=2
上述配置将堆初始化和最大值设为 512MB,并行 GC 线程数为 4,并发 GC 线程数为 2。这种配置在多核服务器上较为常见,旨在平衡应用响应时间和 GC 吞吐量。执行该命令后,JVM 将使用 CMS 进行老年代回收,而年轻代仍默认使用 Parallel Scavenge 收集器(在 JDK 8 中)。
立即学习“Java免费学习笔记(深入)”;
CMS 与其他收集器的兼容性与冲突处理
在使用 -XX:+UseConcMarkSweepGC 时,必须注意它不能与其他老年代收集器同时启用。例如,如果同时设置了 -XX:+UseG1GC 或 -XX:+UseParallelOldGC,JVM 可能会报错或忽略其中一个配置。在 JDK 8 中,默认情况下启用 Parallel GC 时,老年代使用的是 Parallel Old,若希望使用 CMS,则必须显式开启 -XX:+UseConcMarkSweepGC,此时老年代回收算法会自动切换为 CMS。此外,-XX:+UseParNewGC 通常与 CMS 搭配使用以加速年轻代回收,但在某些 JDK 版本中,启用 CMS 会自动启用 ParNew。

-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+UseCMSCompactAtFullCollection -XX:CMSInitiatingOccupancyFraction=70
这段代码展示了 CMS 的典型完整配置。除了启用 CMS 和 ParNew 外,还启用了 -XX:+UseCMSCompactAtFullCollection 以在 Full GC 后进行压缩,减少内存碎片。同时,-XX:CMSInitiatingOccupancyFraction=70 设置了老年代使用率达到 70% 时触发 CMS 回收,避免默认的 92% 阈值导致内存不足风险。这种配置有助于降低 Full GC 的频率,提升系统稳定性。
CMS 触发条件与监控指标分析
CMS 收集器的触发机制基于老年代的内存使用率。当老年代空间达到设定的阈值(默认为 92%,可通过 -XX:CMSInitiatingOccupancyFraction 调整)时,CMS 会启动并发标记过程。这一过程不会阻塞应用线程,但会消耗一定的 CPU 资源。监控 CMS 的效果可以通过 JMX 或命令行工具如 jstat 来实现。例如,使用 jstat -gcutil <pid></pid> 可以查看各代的使用率和 GC 次数。重点关注 OCY(老年代使用率)和 FGC(Full GC 次数)。如果 FGC 频繁发生,可能意味着 CMS 未能及时回收,或者发生了 CMS 失败回退到 Serial Old 的情况。


















