CMS之promotion failedconcurrent mode failure
CMS并行GC收集器是大多数JAVA服务应用的最佳选择,然而, CMS并不是完美的,在使用CMS的过程中会产生2个最让人头痛的问题:
promotion failed
该问题是在进行Minor GC时,Survivor Space放不下,对象只能放入老年代,而此时老年代也放不下造成的。(promotion failed时老年代CMS还没有机会进行回收,又放不下转移到老年代的对象,因此会出现下一个问题concurrent mode failure,需要stop-the-wold 降级为GC-Serail Old)。
下面是一个promotion failed的一条gc日志:
106.641: [GC 106.641: [ParNew (promotion failed): 14784K->14784K(14784K), 0.0370328 secs]106.678: [CMS106.715: [CMS-concurrent-mark: 0.065/0.103 secs] [Times: user=0.17 sys=0.00, real=0.11 secs]
(concurrent mode failure): 41568K->27787K(49152K), 0.2128504 secs] 52402K->27787K(63936K), [CMS Perm : 2086K->2086K(12288K)], 0.2499776 secs] [Times: user=0.28 sys=0.00, real=0.25 secs]
concurrent mode failure
该问题是在执行CMS GC的过程中同时业务线程将对象放入老年代,而此时老年代空间不足,或者在做Minor GC的时候,新生代Survivor空间放不下,需要放入老年代,而老年代也放不下而产生的。
下面是一个concurrent mode failure的一条gc日志:
0.195: [GC 0.195: [ParNew: 2986K->2986K(8128K), 0.0000083 secs]0.195: [CMS0.212: [CMS-concurrent-preclean: 0.011/0.031 secs] [Times: user=0.03 sys=0.02, real=0.03 secs]
(concurrent mode failure): 56046K->138K(57344K), 0.0271519 secs] 59032K->138K(65472K), [CMS Perm : 2079K->2078K(12288K)], 0.0273119 secs] [Times: user=0.03 sys=0.00, real=0.03 secs]
下面我们详细的分析这两个问题产生的原因以及如何进行解决。
首先我们经常遇到promotion failed问题,这也确实是个很头痛的问题,一般是进行Minor GC的时候,发现Survivor空间不够,所以,需要移动一些新生带的对象到老年带,然而,有些时候尽管老年代有足够的空间,但是由于CMS采用标记清除算法,默认并不使用标记整理算法,可能会产生很多碎片,因此,这些碎片无法完成大对象向老年带转移,因此需要进行CMS在老年带的Full GC来合并碎片。
这个问题的直接影响就是它会导致提前进行CMS Full GC, 尽管这个时候CMS的老年代并没有填满,只不过有过多的碎片而已,但是Full GC导致的stop-the-wold是难以接受的。
解决这个问题的办法就是可以让CMS在进行一定次数的Full GC(标记清除)的时候进行一次标记整理算法,CMS提供了以下参数来控制:
-XX:UseCMSCompactAtFullCollection -XX:CMSFullGCBeforeCompaction=5
也就是CMS在进行5次Full GC(标记清除)之后进行一次标记整理算法,从而可以控制老年代的碎片在一定的数量以内,甚至可以配置CMS在每次Full GC的时候都进行内存的整理。
另外,有些应用存在比较大的对象朝生熄灭,这些对象在救助空间无法容纳,因此,会提早进入老年代,老年代如果有碎片,也会产生promotion failed, 因此我们应该控制这样的对象在新生代,然后在下次Minor GC的时候就被回收掉,这样避免了过早的进行CMS Full GC操作,下面的一个配置样例就通过增加Survivor空间的大小来解决这个问题:
-Xmx4000M -Xms4000M -Xmn600M -XXmSize=500M -XX:MaxPermSize=500M -Xss256K -XX:+DisableExplicitGC -XX:SurvivorRatio=1 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled eCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=0 -XX:+CMSClassUnloadingEnabled -XX:LargePageSizeInBytes=128M -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=80 -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+PrintClassHistogram -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -Xloggc:log/gc.log
上面讨论了promotion failed引起的原因以及解决方案,除了promotion failed还有一个情况会引起CMS回收失败,从而退回到Serial Old收集器进行回收,我们在线上尤其要注意的是concurrent mode failure出现的频率,这可以通过-XX:+PrintGCDetails来观察,当出现concurrent mode failure的现象时,就意味着此时JVM将继续采用Stop-The-World的方式来进行Full GC,这种情况下,CMS就没什么意义了,造成concurrent mode failure的原因是当minor GC进行时,1)旧生代所剩下的空间小于Eden区域+From区域的空间,或者2)在CMS执行老年代的回收时有业务线程试图将大的对象放入老年代,导致CMS在老年代的回收慢于业务对象对老年代内存的分配。
解决这个问题的通用方法是调低触发CMS GC执行的阀值,CMS GC触发主要由CMSInitiatingOccupancyFraction值决定,默认情况是当旧生代已用空间为68%时,即触发CMS GC,在出现concurrent mode failure的情况下,可考虑调小这个值,提前CMS GC的触发,以保证旧生代有足够的空间。
总结:
- promotion failed – concurrent mode failure
Minor GC后, Survivor空间容纳不了剩余对象,将要放入老年代,老年代有碎片或者不能容纳这些对象,就产生了concurrent mode failure, 然后进行stop-the-world的Serial Old收集器。
解决办法:-XX:UseCMSCompactAtFullCollection -XX:CMSFullGCBeforeCompaction=5 或者调大新生代或者Survivor空间
- concurrent mode failure
CMS是和业务线程并发运行的,在执行CMS的过程中有业务对象需要在老年代直接分配,例如大对象,但是老年代没有足够的空间来分配,所以导致concurrent mode failure, 然后需要进行stop-the-world的Serial Old收集器。
解决办法:+XX:CMSInitiatingOccupancyFraction,调大老年带的空间,+XX:CMSMaxAbortablePrecleanTime
总结一句话:使用标记整理清除碎片和提早进行CMS操作。
【转自】https://my.oschina.net/hosee/blog/674181
CMS之promotion failedconcurrent mode failure相关推荐
- CMS垃圾收集器详解
概述 CMS垃圾收集器是一款优秀的老年代并发垃圾收集器,通过与用户线程并发执行的方式减少GC停顿的时间.本文主要聊一下CMS设计到的相关的数据结构.具体的执行过程.运行中会出现的异常情况. 在CMS之 ...
- 总结CMS常见面试题
谈谈对CMS的认知? CMS(concurrent mark sweep)在jdk1.5中已经开始使用了,2004年9月30日,JDK1.5发布.CMS设计的目标就是获取最低停顿时间(stop the ...
- 0 full gc时cpu idle_结合GC日志讲讲CMS垃圾收集器
1 CMS垃圾收集器介绍 CMS(Concurrent Mark Sweep)收集器旨在获取最短回收停顿时间的并发垃圾收集器.CMS基于"标记-清除"算法实现,并发指的是CMS的垃 ...
- CME CMS ERROR错误代码
Error Description 4G通信模块指令错误码描述 CME ERROR's (GSM Equipment related codes) CME ERROR: 0 Phone failure ...
- 在linux上gc日志详解,JVM CMS GC日志详解
# JDK8 -Xms20M -Xmx20M -XX:+PrintGCDetails -XX:+UseConcMarkSweepGC CMS 日志格式: [GC (Allocation Failure ...
- 炸了!一口气问了我18个JVM问题!
young gc.old gc.full gc.mixed gc 傻傻分不清? 这个问题的前置条件是你得知道 GC 分代,为什么分代.这个在之前文章提了,不清楚的可以去看看. 现在我们来回答一下这个问 ...
- 面试官不讲武德,竟然问了我18个JVM问题!
前言 GC 对于Java 来说重要性不言而喻,不论是平日里对 JVM 的调优还是面试中的无情轰炸. 这篇文章我会以一问一答的方式来展开有关 GC 的内容. 本文章所说的 GC 实现没有特殊说明的话,默 ...
- JVM面试题(含答案和图和解释)
整理不易,如果对你有帮助,请点赞收藏+关注,请仔细阅读,个别问题涉及到的知识点比较多,看似只有[121],但是扩展的问题还是很多的,所以料很足,请耐心观阅,面试题包含了[类加载机制][运行时数据区][ ...
- 学习笔记【Java 虚拟机②】垃圾回收
若文章内容或图片失效,请留言反馈.部分素材来自网络,若不小心影响到您的利益,请联系博主删除. 总目录 学习笔记[Java 虚拟机①]内存结构 学习笔记[Java 虚拟机②]垃圾回收 学习笔记[Java ...
最新文章
- android tombstone发生过程,Android Tombstone 分析
- 北京发自动驾驶车辆考试大纲 难度堪比普通人考驾照
- collection_check_boxes的应用
- tRNAscan-SE 预测tRNA基因
- UITableView样式和UITableViewCell样式
- crash工具解析_Linux 后台开发常用调试工具
- 英语发音规则---发/i:/的字母及字母组合
- 九、Spark模块和安装
- 数仓dw怎么建_搭建数据仓库的流程简介
- Android之如何ubuntu环境下在手机里面快速找到apk的位置然后拉下来
- 于.net开发平台项目案例集锦
- HBase-scan简介及优化(缓存与批量处理)
- VS Code 取色器 插件 颜色选取
- 用注册表修改右键菜单
- Java中Math类的随机数公式
- C语言数据结构之一元多项式的求导
- C#强密匙加密文件.snk
- Android旅游自助项目之订票系统订票功能实现
- android 电容屏多点触控协议
- 如何将PDF转换Word?微信如何转换PDF文件?
热门文章
- vba移动文件_Excel VBA之FSO-2.3文件夹的移动
- linux终端命令教程,Linux终端命令入坑技巧
- 传统公司部署OpenStack(t版)简易介绍(九)——控制台部署
- 电脑无法连接到系统服务器,请问怎么客户端的电脑连接不到服务器?这是什么原因?...
- C语言面试题分享(3)
- GPT转MBR怎么转?GPT转MBR完整图文教程
- html效果属性是,htmltransition属性
- python缩进格式作用_关于自动缩进格式问题,高手帮忙!
- js打印线程id_一文讲透“进程,线程和协程”
- el-table 行背景颜色_用手机拍花卉怎样使背景变黑?