代码改变世界

测试webservice时,client的JVM内存溢出

2013-01-07 10:57  Joeyyyy  阅读(1681)  评论(0)    收藏  举报

前些日子自己不小心挖了个坑,今天终于自己掉下去了. 在这里记录一下提醒大家~

事件重放


 

事情是这样的: 我们对service做性能测试,如果是使用hessian协议的service, 因为传输的内容是二进制的不好模拟, 一般会采取先在一个测试的web工程中引入client的jar实现待测接口功能,然后让jmeter调用这个测试工程来压待测service.

今天测试一个service,发现每次10min后,测试结果就开始波动. 观察accesslog,发现请求的到达会一卡一卡的. 而响应时间上并未异常.

导致测试应用的cpu由于间隔的无请求到达,变成锯齿状.

 

调查真相


 

调查了被测应用,数据库,memcached,都工作正常, 那问题应该就是出在我们的client hub应用上了.

进一步观察, 果然发现正是由于client hub的内存溢出,导致jvm不停fullgc引起的.

用jmap -histo命令,发现最大的三个对象,占用了所有内存约80%.

java.util.concurrent.locks.ReentrantLock$NonfairSync
java.util.concurrent.ConcurrentHashMap$Segment
[Ljava.util.concurrent.ConcurrentHashMap$HashEntry;

我代码中都是简单处理一下传入参数然后就调用client,并未有直接引用这些对象.

简单起见先bing了一下, 确实有不少人碰到同样的问题, 原来这些是tomcat保存session的对象.session创建后,如果没有手动注销,只有超时后才会被清理,gc是不起作用的, 这个就是我们的罪魁祸首.

解决


 

但是以前怎么没碰到这个问题呢? 原来前些日子自己在改脚本时,无意中禁用了jmeter脚本中的cookie manager. 当时是想着我这些调用并不需要状态,没必要启用cookie. 但是就是这个修改,导致tomcat认为每个请求都是新用户过来的,于是都会创建session进行分配,最后就杯具掉了.

我是重新启用cookie manager, 问题解决了.

补充: 参考网友文章,原来是因为我的结果页面使用了jsp,导致每次请求tomcat自动创建session. 通过加上<%@page session="false"%>也可以解决这个问题.

教训


这里提醒大家,千万不能手贱,洁癖果然是种病啊~!

 

文章参考:

http://ddupnow.iteye.com/blog/621619