当前位置: 首页 > Java > 正文

某java应用在压测一段时间后就会把物理内存耗光

1 星2 星3 星4 星5 星 (3 次投票, 评分: 4.33, 总分: 5)
Loading ... Loading ...
baidu_share

解决过程:
1、从gc log以及jstat信息来看,java heap内的内存消耗并不多,但堆外消耗非常严重,导致了物理内存被耗光;

2、于是装上google perftools,看看堆外到底是什么原因造成的消耗;

3、分析了下google perftools的内存malloc消耗,主要是调用Unsafe.allocate造成的;

4、通常调用Unsafe.allocateMemory来分配内存的,只有Direct ByteBuffer和AWT,这应用是没用AWT的,Direct ByteBuffer倒是用到了;

5、网上google了一会,找到一个貌似和这个应用的场景很像的内存泄露的现象,具体信息请见:http://t.co/S9jvDt8O,号称是SocketChannel.write的时候,如果是Direct ByteBuffer会导致memory leak,而且Trustin Lee(Mina/Netty的作者)也这么说的:”it’s a known bug”;

6、于是建议应用的同学将ByteBuffer的地方改成不用direct方式;

7、改完后,重新压测,物理内存消耗是没那么严重了,但java heap用满了后回收不了了;

8、于是dump内存,用mat分析后发现是由于这个应用本身处理上的一些缺失造成的,简单说下,这个应用是一个基于mina的应用,而应用没有对session上的发送请求做限流,而mina来不及发送,导致积压了很多WriteRequest,从而内存被耗光了;

9、对这个问题的解决方法是:限流,当未发送的字节数到达某个比率后,就暂时先不发送了,或者报错等等,用netty能对这个现象有一定的缓解,但限流动作还是要做,否则可能会出现接收方处理慢,从而导致发送方内存用完的现象。

本文固定链接: http://www.chepoo.com/java-application-cause-mem-full.html | IT技术精华网

某java应用在压测一段时间后就会把物理内存耗光:等您坐沙发呢!

发表评论