- -XX: UseConcMarkSweepGC
新生代使用ParNew回收器,老年代使用CMS回收器。
- 它的特点是,会关心系统的停顿时间。
- CMS全称为Concurrent Mark Sweep,即:并发标记清除。它采用的是标记清除算法。也是多线程并发执行器。分为如下六个步骤:
- 1> 初始标记(STW)
标记根对象
- 2> 并发标记
标记所有对象
- 3> 预清理
清理前的准备以及控制停顿时间
(可以采用-XX:-CMSPrecleaningEnabled关闭,不进行预清理)
为什么要有预清理?
因为第4步重新标记是独占CPU的,如果YoungGC发生后,立即触发一次重新标记,那么一次停顿时间可能很长,为了避免这种情况,预处理时,会刻意等待一次新生代GC的发生,然后根据历史数据预测下一次YoungGC的时间,在当前时间和预测时间取中间时刻执行重新标记操作,目的就是尽量避免YoungGC与重新标记重叠执行。从而减少一次停顿时间。
- 4> 重新标记(STW)
修正并发标记数据
- 5> 并发清理
清理垃圾(真正的执行垃圾回收)
- 6> 并发重置
重置状态等待下次CMS的触发
- 我们可以使用-XX: UseConcMarkSweepGC来启用CMS
- 那么由于它是多线程回收器,我们可以通过-XX:ConcGCThreads和-XX:PartallelCMSThreads设置并发线程数量
- 也可以通过-XX:CMSInitiatingOccupancyFraction来设置当老年代空间使用量达到某百分比时,会执行CMS。默认68,也就是老年代使用空间达到68%的时候,会执行一次CMS回收。
- 由于CMS采用的是标记清除算法,所以不可避免的就是内存碎片,那么我们可以通过如下两个参数进行解决:
- -XX: UseCMSCompactAtFullCollection指定GC后,进行一次碎片整理
- -XX:CMSFullGCsBeforeCompaction 指定执行多少次GC后,进行一次碎片整理