参数
指定cms: -XX:UseConcMarkSweepGC
回收后进行碎片整理
-XX:+UseCMSCompactAtFullCollection
多少次fullgc后进行整理: -XX:CMSFullGCsBeforeCompaction=0
避免浮动垃圾
触发cms回收的比例: -XX:CMSInitiatingOccupancyFraction=55
只是用设置的比例,不让jvm自动调整 -XX:+UseCMSInitiatingOccupancyOnly
四个阶段
初始标记
stw,但是只标记gc roots直接引用的 非常快
并发标记
老年代存活对象比较多,追踪大量对象,耗时比较长
重新标记
stw,这边有可能由于待回收的垃圾对象引用太多,停顿会比较久
并发清理
三个问题
1. 内存碎片
标记-清除算法的缺陷
如何处理,打开2个参数
-XX:+UseCMSCompactAtFullCollection 默认开启,表示fullgc之后 进行内存碎片整理<br>
-XX:CMSFullGCsBeforeCompaction=0 执行多少次fullgc之后 进行一次内存碎片整理<br>默认为0,表示fullgc之后都会整理
2. 消耗cpu资源
gc线程数 = (cpu核数 + 3)/4
并发清理阶段 回收线程和 系统线程同时工作
3. “浮动垃圾”
cms在并发清理阶段,系统还在运行,此时产生的垃圾在本次是处理不了的,称为“浮动垃圾”
如果并发清理时候,老年代空间放不下此时产生的“浮动垃圾”会发生 Concurrent Mode Failure
退化成 Serial Old 再次进行垃圾收集
所以cms收集器要预留一部分空间 -XX:CMSInitiatingOccupancyFaction 触发cms的比例<br>
默认92%
一般设置成55% 、65%