记一次公司jmeter压测时cpu过高,jvm调优解决方案

问题现象

因为涉及到人行征信报文测试的报文有2.7M需要进行特征计算衍生。使用jmeter压力测试发现服务器cpu几乎打满,qps始终只有25左右。换成90k小报文后qps立马就能上到1200后来我使用了一下阿里巴巴的一款Arthas工具打算先分析一下是GC导致的cpu高还是代码中存在死循环之类的代码

解决过程

因为服务器不能连接外网所以从改地址先下载arthas 后再上传到服务器

下载 — Arthas 3.5.4 文档

启动命令:

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不再频繁

如果不是gc导致的cpu异常的高。可以通过thread -n 10这个命令来查看是什么代码消耗cpu资源比较多。

补充:thread -n 10 这个命令只能看到瞬时是cpu资源消耗,有时候为了精准的调优代码,可以通过arthas 输出一个火焰图,上面可以看到单位时间内的cpu消耗从而进行压测调优代码