常见组合
- Serial + CMS + SerialOld(jdk8废弃)
- ParNew + CMS + SerialOld ((jdk9不推荐使用,随着jdk14CMS的废弃,此方案废弃)
特点
- 第一款能和用户线程并发执行的垃圾收集器
- 作用在老年代
- 标记清除算法
- 注重低延迟
- 在cpu核心数较少的机器上效率低下
- 碎片化严重,或OOM前触发SerialOld收集器(STW)进行FullGC
- 因为有致命的缺点,在任何jdk版本都没有作为默认值,但是并不能影响CMS作为优秀的低延迟垃圾收集器
缺点
- 会存在与用户线程竞争cpu运算资源的情况,导致用户线程执行变慢。
- 由于gc和用户线程并发执行,需要堆内存到达一定比例时就要开始gc,在并发标记过程中,如果与gc Root直接关联的对象成为了垃圾(也就是浮动垃圾),这个垃圾就要等到下一次gc时才能被清理。gc结束后,如果堆内存还不满足分配需要,此时就会触发SerialOld收集器(STW)进行FullGC,单线程收集。
- 因为采用标记清除算法,产生碎片化,如果需要分配较大连续的内存,此时堆中的情况不满足分配内存的需要时,也会触发SerialOld进行FullGC。
运行图
使用CMS
- 使用cms: -XX:+UseConMarkSweepGC
- 触发gc已使用堆内存占比: -XX:CMSlnitiatingOccupanyFraction(jdk5默认是68,jdk6及以后92)
- 执行fullGC后整理内存:-XX:+UseCMSCompactAtFullCollection
- 指定fullGC次数之后压缩内存: -XX:CMSFullGCsBeforeCompaction
- gc和用户线程并发时cms的线程数量: -XX:ParallelCMSThreads默认(核心数+3)/4