上篇文章介绍用户线程与GC线程并发执行时可能产生的问题以及应用三色标记法演示原始快照和增量更新两种解决方案
这篇文章将次要介绍并发垃圾收集器中的CMS,其中CMS应用增量更新来解决对象隐没问题,如果不理解增量更新的同学能够查看上篇文章深入浅出JVM(十六)之三色标记法与并发可达性剖析
前言
前文形容过,当GC时须要枚举的GC根节点须要极短的进展(STW)
而在遍历GC援用链时,如果用户线程是进展的,那么不会扭转援用,GC线程遍历标识即可
但随着堆内存中对象的增多,援用链会越来越长,如果继续让用户线程进展,在某些须要低提早的场景是不现实的
因而心愿能在这个环节让用户线程和GC线程可能并发执行,并发执行就会存在扭转对象援用,可能导致对象隐没问题,其中能够应用增量更新和原始快照的形式解决,而CMS应用的就是增量更新
Concurrent Mark Sweep
CMS全称Concurrent Mark Sweep 并发标记革除收集器
CMS是老年代收集器,采纳标记-革除算法,年老代罕用ParNew收集器,以最短进展工夫(低提早)为指标的收集器
CMS并没有应用标记-整顿算法,因为标记、清理阶段是和用户线程并发执行的,如果应用标记-整顿算法可能会导致挪动援用的地位导致出错
执行步骤
- 初始标记: 标记GC Roots间接关联的对象(STW工夫极短)
- 并发标记: 从GC Roots间接关联对象开始遍历整个援用链的过程(耗时长,不须要进展用户线程,用户线程与GC线程并发执行)
- 从新标记: 应用增量更新防止对象隐没问题,修改并发标记期间改变的对象(须要STW,耗时比步骤1长,比步骤2短)
- 并发革除: 清理标记阶段判断已死亡的对象、重置状态等(该阶段也是并发执行)
执行图
参数设置
-XX:UseConcMarkSweepGC
- 老年代应用CMS垃圾收集器,新生代应用ParNew收集器
-XX:CMSInitiatingOccupancyFraction
设置老年代应用多少空间时开始垃圾回收
- 如果设置的太高,不够内存调配,不能满足并发执行,就会解冻用户线程启动Serial Old收集器,进展工夫就会变长
- 如果内存增长迟缓能够设置高一些,如果内存增长很快就要设置低一些 默认92%
-XX:+UseCMSCompactAtFullCollection
- 指定在FULL GC后是否对内存进行压缩整顿
- 开启后,通过
-XX:CMSFullGCsBeforeCompaction
设置执行多少次FULL GC后进行内存压缩整顿
-XX:ParallelCMSThreads
- 设置GC线程数量
特点
长处:
进展工夫短
只在初始标记,从新标记时STW
并发执行
工夫长的并发标记和并发清理与用户线程,放慢响应速度,晋升用户体验
毛病:
吞吐量升高
在处理器核数少时,GC线程与用户线程并发执行(应用i-CMS解决:缩小GC线程独占工夫,垃圾回收工夫变长,对用户线程执行影响变小)
无奈解决浮动垃圾
增量更新通过记录新增援用来防止对象隐没问题,可能呈现浮动垃圾(不能在这一次的GC中被回收,只能下一次GC时被回收)
CMS不能等老年代满了再垃圾回收,因为与用户线程并发执行,所以须要留一部分内存
内存碎片多
屡次垃圾回收后进行一次标记-整顿算法,采纳替补计划Serial Old
总结
本文依据并发垃圾收集器CMS深入浅出的解析CMS执行流程、优缺点以及配置参数等
CMS是一款主打低提早、应用标记-革除算法的老年代并发垃圾收集器,年老代常应用ParNew
CMS在初始标记时进行STW,接下来遍历援用链时与用户线程并发执行,而后让用户线程短暂STW应用增量更新进行从新标记,最初在并发进行清理、重置等工作
CMS的特点是在遍历援用链、清理时并发执行,可能使用户线程的进展工夫变短;然而带来吞吐量的升高,并且增量更新会导致浮动垃圾的呈现,因为老年代应用标记-革除算法,不整顿内存将会导致大对象无奈存储,替补计划是应用Serial Old单线程标记-整顿
如果老年代内存不足或须要整顿内存时,会应用Serial Old 单线程解决,这可能导致提早更高,在高版本中曾经有G1等其余垃圾收集器代替CMS,CMS在JDK14时被移除
最初(一键三连求求拉~)
本篇文章将被支出JVM专栏,感觉不错感兴趣的同学能够珍藏专栏哟~
本篇文章笔记以及案例被支出 gitee-StudyJava、 github-StudyJava 感兴趣的同学能够stat下继续关注喔\~
有什么问题能够在评论区交换,如果感觉菜菜写的不错,能够点赞、关注、珍藏反对一下\~
关注菜菜,分享更多干货,公众号:菜菜的后端私房菜
本文由博客一文多发平台 OpenWrite 公布!