最近同事在用 Jmeter 做性能测试,出现了问题找我帮忙排查,问题是Jmeter开到50个并发就会出现如下几个现象:

1、压测到了2分钟左右的时候就必定会导致Jmeter卡死;
2、nmon曲线在2分钟直线下降至完全没有请求。
3、压到最后时Jmeter控制台出现如下报错:GC OverHead limit exceed。

经了解,GC OverHead limit exceed 的原因是,JVM进程内存不足,虚拟机进而启用GC(垃圾回收),但是回收出来的那部分空间很快又会被进程吃掉,于是又继续跑GC,以此类推,以至于JVM绝大部分资源都用于跑GC了,压根就没怎么跑正常的任务了,进而导致上述报错。其实总结一句话就是,内存被耗光了。

于是,按照了解到的方法,把 Jmeter.bat 里面的 Head 的堆空间最大值从默认的512M调整到2G甚至8G,重跑问题依旧,且依然是在2分钟左右卡死。

但我就纳闷了,Jmeter就是负责发几十个请求出去而已,哪能耗多少内存。

然后,靠着程序员的基本意识,开始思考Jmeter究竟干了啥事会这么耗内存,我从头看了一遍同事的Jmeter案例和脚本,案例脚本都很简单,没啥操作,不会耗什么内存,但我发现我们性能测试的时候开着一个叫“察看结果树”的东西,这玩意是用来记录http请求和http应答报文的,只是用来观察请求和应答是否成功。好,这玩意很简单,好像不应该影响我们的性能测试?

但是,关键在于,Jmeter的几乎所有操作都是在内存中完成的!也就是说“察看结果树”里面的所有内容都会在内存中累积!算笔账,假设我们不间断(无线程延迟)地跑,10ms处理一个请求,那也就是1s能有100个请求和应答,然后乘以50个并发,那就是1秒的时间,在“察看结果数”中会有5k个网页(5k应答网页,另外还有5k个http请求),然后2分钟后,内存会累积了多少个http报文?

顿悟!于是把“察看结果树”在开始测试前禁用,然后全程跑下来非常顺利,Jmeter宿主机也没啥性能压力。问题解决。

所以Jmeter测试时,需要记得一个常识,就是要关闭“察看结果树”!

“察看结果树”这玩意就是在编写调试Jmeter脚本的时候用的,千万不要把它也放到测试时运行。