首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

使用Mina出现的JNI OutOfMemory的解决办法

2012-10-28 
使用Mina出现的JNI OutOfMemory的解决方法最新在使用MINA作了UDP服务器和UDP客户端,在最后性能测试时,总是

使用Mina出现的JNI OutOfMemory的解决方法
最新在使用MINA作了UDP服务器和UDP客户端,在最后性能测试时,总是遇到OutOfMemory的问题,很是郁闷,定位了三天,后来终于找到了解决方法。和大家分享一下,以免大家再走同样的弯路。

我们性能测试场景如下:
Client起100个线程同时向Server发UDP消息,Server接收到请求后立即向Client回响应;
在前10秒内,服务器响应特别快,大概每秒可以达到4000个消息,但到了10多秒后,服务器的响应就越来越慢,后来基本上就不响应,又或者直接OutOfMemory,并出现下面的错:
request <size> bytes for <reason>. Out of swap space?

一开始我们一直以为是缓存中的对象未清理掉而导致的问题,定位了一段时间后,发现缓存中的内容已经及时清理了。打开GC日志,也没有发现问题。

后来,我们就开始上网狂找资料,发现原来Java内存分为两种,Heap内存和JVM使用的内存,
Heap内存就是一般的JAVA对象使用内存;
JVM使用的内存,就是指JVM在运行过程中要使用的内存,JVM最终要通过调用JNI,本地方法运行也是需要内存的,这部分内存JVM直接向OS申请。

既然我们自己的代码中使用的JAVA对象已经及时清理,那是不是JNI内存泄漏了?可是我们的代码,基本上没有使用JNI啊。难道是MINA的问题?大概看了下MINA的源码,MINA是使用Java的NIO包下的类来实现的,打开Java的-verbose:jni选项,可以看出,NIO中的类很多都是通过JNI来实现的。

好了,继续定位,发现我们的代码中,大量使用了MINA提供的IoBuffer类,MINA为我们构造了大量的IoBuffer对象,我们自己也构造了大量的IoBuffer对象,会不会这个类的对象没有及时清理?

带着疑问,我看了IoBuffer的所有方法,其中有个free()方法,看了注释,是用来清理内存的。
于是尝试在所有使用完IoBuffer的代码处都加上了调用free()方法的代码,再进行测试,终于OK了。

UDP服务器稳定运行后,内存最大只使用了200多M,问题搞定。

所有使用Java的NIO包下的类,最好都多注意下JDK文档,看是否需要主动调用某方法来释放内容。 1 楼 dennis_zane 2008-09-06   你们用的是Direct ByteBuffer吧,Direct ByteBuffer是在虚拟机之外分配内存的,因此设置-Xmx并不会有作用,这个大小可以通过-XX:MaxDirectMemorySize=<size>参数来调节。free()方法并没有要求强制调用,但是主动调用的话可以提高性能表现。

2 楼 zhao3546 2008-09-06   调用IoBuffer.free()方法后,不再出现异常,内存使用很稳定。
谢谢 dennis_zane 的指点。
我再试试你说的方法,看性能会不会有提升。 3 楼 shijiyu 2008-10-07   初学 还没给晕倒你们的问题 (*^__^*) 嘻嘻……

热点排行