问题现象
因为涉及到人行征信报文测试的报文有2.7M需要进行特征计算衍生。使用jmeter压力测试发现服务器cpu几乎打满,qps始终只有25左右。换成90k小报文后qps立马就能上到1200后来我使用了一下阿里巴巴的一款Arthas工具打算先分析一下是GC导致的cpu高还是代码中存在死循环之类的代码
解决过程
因为服务器不能连接外网所以从改地址先下载arthas 后再上传到服务器
https://arthas.gitee.io/download.html
启动命令:
java -jar arthas-boot.jar
然后回车输入:dashboard 用于查看cpu,内存,GC等情况
可以看出大半的cpu资源都是被GC回收所占用。
接下来的问题就是要解决GC频繁的问题了。
使用:jstat -gcutil 进程号 1000 1000 示例:jstat -gcutil 11051 1000 1000
查看到 full GC发生频繁,而且 O 列很明显每次GC后回收了一半的内存空间。(此处还有一种情况,就算full GC频繁,但是O列的内存空间几乎没什么变化,这种情况大概率就是代码里有很多对象放到老年代始终无法回收,需要具体到代码成名分析了,Arthas也可以做到,此处就不再讲述了)
那么很明显了,我了解到的对象会加入老年代有两种情况:1,对象经过15次gc后会从年轻代挪到老年代;2,一次插入的对象太大了超过了年轻代空间的1/2会直接挪到老年代。
很显然我们的问题应该是第二种情况,因为body体中的一个请求就有2.7M.
解决方法:由于jvm默认的年轻代和老年代空间大家比例是1:2。故将老年代的空间调大即可,从而避免以上第二种情况的发生。
vi ~/.bash_profile 将年轻代调整为10G
source ~/.bash_profile
再测qps提升了近4倍,GC不再频繁了