jmeter内存泄露导致闪退的问题处理
问题描述:
在压测过程中偶然遇到了一次压力机jmeter内存无法分配(cannot allocate memory)的问题,重复压测内存问题仍是无法解决,后进行一些分析判断后逐步定位到问题所在,以记录下来,以便后续查阅复盘。
所压场景为一个录入接口,但是参数需要从场景关联接口中获取,所以压测场景分为三个接口,请求方式都为post (后发现有一个查询接口为get请求):
压测加压策略为梯度加压(Stepping Thread Group),目的是在整个压测过程中观测不同情况下系统的反应情况,压测效果好于普通加压线程组:
在已经完成性能优化之后,再次进行压测时发现jmeter并发能力减弱(直观感受),实际为接口响应时间、数据库CPU消耗优化效果明显,但tps较低,无法满足正常压测标准,且在梯度加压第二次时(200–>400)jmeter崩溃闪退,报错如下图
问题分析解决:
**1.**通过返回报错结果可以直接判断出崩溃闪退是因为jmeter无可用分配内存导致,由此确定后续分析判断方向;
**2.**解决思路1:增大jmeter运行可分配空间。查看jmeter配置文件,将apache-jmeter-5.4.1/bin目录中的jmeter配置文件修改:找到内存配置行
: “${HEAP:=”-Xms1g -Xmx1g -XX:MaxMetaspaceSize=256m"}"
将其改成压力测试机器所适配的内存大小
: “${HEAP:=”-Xms1g -Xmx8g -XX:MaxMetaspaceSize=1024m"}"
重新压测结果:有效果,但仍旧崩溃闪退;
3.1解决思路2:寻找内存占用原因。
猜测内存泄露原因为前两个查询接口加了大对象的json提取器导致压测时消耗了太多的可分配空间,验证方式为禁用掉前面两个查询接口的json提取器和录入接口(防止功能报错)。
重新压测结果:依旧崩溃闪退,猜测验证失败;
3.2解决思路2:寻找内存占用原因。
猜测内存泄露原因为硬件原因,更换压测机器,用相同脚本再次压测,对比验证。
压测结果:依旧崩溃闪退,猜测验证失败;
3.3解决思路2:寻找内存占用原因。
猜测内存占用与所压测接口有关,对单接口进行压测。
压测结果:压测第一个查询接口时表现良好,未出现崩溃闪退的情况,而在压测第二个查询接口的时候jmeter出现崩溃闪退的情况,以此定位到脚本中第二个查询接口是jmeter出现崩溃闪退的原因;
4.1继续深入分析问题出现原因
由于前面两个接口都为查询接口,且业务逻辑类似,压测结果迥异,因此采用对比分析的方法进行分析判断:
查询接口1:
查询接口2:
通过对比发现两个接口的请求方式不同,请求传参的方式不同,但是请求方式固定无法改变,只能在请求传参的方式做调整。jmeter自带固定参数的传参方法(同请求一起发送参数)可能会增加一次读取转化的过程,该过程可能会消耗较多空间,再加上该请求为get方式,无法采用json格式传参,因此调整传参方式:将参数直接拼入url中,减少jmeter读取转化的过程。
调整后结果:
压测结果:未出现崩溃闪退现象,且压测过程中tps、响应时间表现出良好的加压能力,然后对全场景三个接口进行压测,仍旧未出现崩溃闪退现象。
结果整理:
1.jmeter内存固定,需要手动调整以适应当前压力测试机器的资源配置和压测策略
2.并发压测过程对所在压测机器的资源也是较大的考验,因此在写压测脚本时还应该考虑内存消耗问题,如:一般用来获取大量的可重复参数的csv文件设置,不宜选择过大的文件进行读取传参,会严重影响内存分配和所在机器加压能力,
3.压测出现崩溃闪退问题时,会自动打印报错日志且输出为log文件,存放目录为:apache-jmeter-5.4.1/bin