## 一 . 背景
> 夜间2-3点钟,程序员好不容易躺下要休息了。。。数据又推送了 。。。机器报警非常准时....机器cms gc失败,导致进行多次full gc 暂停服务。
## 二 . cms gc过程##

####<font color ='red'>cms gc过程存在两次暂停</font>
## 三 . gc log
###详细分析gc 日志
内存变动如图

>图片有些不清晰,受大小限制 ,附件详细gc log的分析过程
## 四 . 问题概述
> gc log里面大量存在concurrent mode failure 失败,导致jvm 进行fullgc, stop -the-wold,反映如下问题
<font color ='red'>
###1在推送build本地缓存的过程中,大量对象产生,极其频繁,ygc的频率达到了5s左右一次,正常的夜间业务ygc在50s一次.
###2 cms gc过程中old区剩余空间不足,old区已经不能容忍新晋升的数据.并数据反序列化过程中old区需要多次full gc
###3 平常的old区已经达到63%,build过程中数据一定需要old区替换,需要进行多次的cms gc才能替换数据完成。
###4原有jvm参数 如图

</font>
## 五. 解决方案
###1 增大yong区回收高效性,可能性
>减少yong区晋升到old区数据,最大程度在yong区垃圾回收,减少old区垃圾回收频率,调整 参数-XX:MaxTenuringThreshold=50000
线上机器观察,无意义...后面系分原因
###2 增大old区内存空间
>2.1 调大整个jvm内存,yong区不变,增加old区,减少应用堆外内存。
目前应用共有8g内存,3个jvm。。应用本身单机高qps,写日志极其频繁。。。无法挪用堆外内存,增加虚拟机内存暂不考虑
>2.2 降低yong区,调整xmn参数从2G到1.5G,相当于old区空间从3G变到了3.5G.并且调整old区触发cms gc的百分比从75%降低到70%。相当于old区在触发cms gc的情况下,空闲内存增加了0.2G。。
修改后ygc的频率增加,从原来的夜间50s变成40s,白天基本10s一次ygc..压测对应用qps没有影响。
并且白天观察并不触发cms gc,夜间 推送数据build不再失败,不再触发fullgc
线上观察几天不再出现gc失败问题。。
####3 增加yong区
>3.1考虑过增大yong区 来解决问题,但是过程中yong区一直增大,频率较高。old区在平常已经达到了63%,应用是一定要进行fullgc才能把原有old区对象替换掉,新build的对象才能进入old区,这个时期cms gc失败了,触发了full gc。。问题就又回到了原点
## 六.cms gc 哪些坑
###1 无用参数
> 调整年轻代的gc次数,年轻代回收的值修改到 -XX:MaxTenuringThreshold=50000
线上观察根本没有起作用
原因如图

这个字段是age,给它分配的就是4个bit,因为最大不会超过16就会被回收
这个jvm默认值就为15。。。。
###2
parnew:暂停应用 只是暂停的时间比较短,上层应用感知不明显
## 七. 题外action
欢迎大家多提意见以及改进方案