测试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"%>也可以解决这个问题.
教训
这里提醒大家,千万不能手贱,洁癖果然是种病啊~!
文章参考:
浙公网安备 33010602011771号