# CMS (Concurrent-Mark-Sweep)
CMS的好处是低延迟(低STW),并行统计GCRoot
CMS在JDK9已经被废弃了,在JDK14就撤出历史舞台了
# CMS工作流程
# 初始标记阶段(Initital Mark)
先STW一次,仅仅标记能直接关联的GCRoot
# 并发标记阶段(Concurrent Mark)
与其他线程同步执行,顺着第一步标记的GCRoot向下遍历,找出所有关联对象,因为这一步很耗时,所以并发执行,大大减少STW时间,是CMS关键所在
# 重标记阶段(Remark)
并发标记过程中,其他线程也在执行,有引用更新调整的情况发生,所以需要STW一下,重新标记一次
TIP
这里涉及到一个Card Table的概念
并发标记阶段过程中,出现变更的对象会被记录在Card Table里
这样可以大大提高Remark阶段的效率
# 并发清除阶段 (Concurrent Sweep)
标记好之后,再并发清除
# 参考文章
https://www.jianshu.com/p/a88dabfc2f60
# 弊端
# 内存碎片
因为是并行清理的,只清理垃圾,不能调现有引用的地址,所以无法避免产生许多的内存碎片
# 浮动垃圾
在清理过程中,可能还会产生新的垃圾,无法避免的,只能等待下一次GC触发
# 触发Serial Old清理
老年代内存碎片太多了,没办法担保分配了,会触发Serial Old进行FullGC,而Serial Old又是串行的STW,效率很差 CMSInitiatingOccupancyFraction是CMS的老年代内存达到一定的百分比之后触发Serial Old的阈值
# 适用场景
- 追求低延迟的强调用户体验的应用
- 内存不是特别大的,6G以下,如果内存特别大,那么真触发了一次Serial Old,FullGC大内存很麻烦,影响CMS口碑