关于jvm:CMS收集器中两个致命的问题

41次阅读

共计 1198 个字符,预计需要花费 3 分钟才能阅读完成。

CMS是一个很好的并发垃圾收集器, 然而应用过程中会产生两个重要的问题。

  • promotion failed 降职失败
  • concurrent mode failure 收集器无奈解决浮动垃圾

promotion failed 降职失败起因

该问题产生在 Minor GC 过程中,Survivor Space放不下转移的对象, 老年代也放不下(promotion failed 产生的时候老年代 CMS 还没有机会进行回收, 又放不下转移到老年代的对象, 下一步就会产生concurrent mode fialure, 产生 STW 降级为 Serial Old)

上面是一条 promotion failed 失败的日志

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 产生的起因

concurrent mode failureCMS 特有的谬误,CMS的垃圾清理线程和用户线程是并行进行的. 老年代正在清理, 从年老代降职了新对象,或者调配的大对象在新生代放不下, 间接在老年代分配内存, 这时老年代也放不下, 则会抛出concurrent mode failure

concurrent mode failure 的影响

老年代的垃圾收集器从 CMS 进化成Serial Old, 所有用户线程被暂停, 进展工夫变长。

解决方案

CMS 触发太晚

-XX:CMSInitiatingOccupancyFraction=N 是指设定 CMS 在对内存占用率达到 N% 的时候开始 GC(因为 CMS 会有浮动垃圾, 所以个别都较早启动 GC);

  • 将:-XX:CMSInitiatingOccupancyFraction=N调小

空间碎片太多

开启空间碎片整顿, 并将空间碎片整顿周期设置在正当范畴,-XX:CMSFullGCsBeforeCompaction作用:设置在执行多少次 Full GC 后对内存空间进行压缩整顿。

  • -XX:+UseCMSCompactAtFullCollection(空间碎片整顿)
  • -XX:CMSFullGCsBeforeCompaction=n

垃圾产生太快

  • 降职阈值太小
  • Survivor 空间过小
  • Eden 区过小, 导致降职速率过快
  • 存在大对象

正文完
 0