浏览 5589 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-09-05
我们性能测试场景如下: 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文档,看是否需要主动调用某方法来释放内容。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-09-06
你们用的是Direct ByteBuffer吧,Direct ByteBuffer是在虚拟机之外分配内存的,因此设置-Xmx并不会有作用,这个大小可以通过-XX:MaxDirectMemorySize=<size>参数来调节。free()方法并没有要求强制调用,但是主动调用的话可以提高性能表现。
|
|
返回顶楼 | |
发表时间:2008-09-06
调用IoBuffer.free()方法后,不再出现异常,内存使用很稳定。
谢谢 dennis_zane 的指点。 我再试试你说的方法,看性能会不会有提升。 |
|
返回顶楼 | |