线上gc优化实践

## 一 . 背景

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


## 二 . cms gc过程##

![cms_gc](http://img3.tbcdn.cn/L1/461/1/83a945d49ac1bbd72209d3c82611d2500135c15b)



####<font color ='red'>cms gc过程存在两次暂停</font>



## 三 . gc log 


###详细分析gc 日志


内存变动如图

![](http://i.imgur.com/0HTfNxt.png)



>图片有些不清晰,受大小限制 ,附件详细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参数 如图

![](http://i.imgur.com/BUzjJ9I.jpg)

</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

线上观察根本没有起作用


原因如图

![](http://i.imgur.com/QDSm22r.png)

这个字段是age,给它分配的就是4个bit,因为最大不会超过16就会被回收 


这个jvm默认值就为15。。。。


###2

parnew:暂停应用 只是暂停的时间比较短,上层应用感知不明显



## 七. 题外action




欢迎大家多提意见以及改进方案


你可能感兴趣的:(线上gc优化实践)