面试题31:垃圾收集器——CMS回收器

2023-05-09 21:39:27 浏览数 (2)

  • -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后,进行一次碎片整理

0 人点赞