精华帖 (0) :: 良好帖 (2) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-06-20
在做网络监控系统的性能测试时,出现了内存泄露的问题,困扰了很久,现在终于算是解决了,但是根本原因尚不明确,拿出来大家讨论下,看看能不能完美解决~ 这个问题奇怪的地方在于是Java进程内存泄露,而不是平常的JVM内存泄露,用Jprofile等工具也无法看出问题所在。 测试代码如下: System.loadLibrary("test1"); int threadPoolSize = 400; ExecutorService service = Executors.newFixedThreadPool(threadPoolSize); for (int i = 0; i < 400; i++) { service.submit(new Runnable() { public void run() { while (true) { try { Thread t = new Thread(); t.start(); Thread.sleep(100); } catch (Exception e) { e.printStackTrace(); } } } }); } 说明:此段代码所做的工作就是加载一个dll,然后不断的启动线程(线程什么也不做,直接终止)。 注:线程池只是为了加速问题复现,无其他用处。 现象: 1.如果不加载dll,只不断的启动线程,Java进程内存正常,不会一直增长。 2.如果加载附件中test1的dll,Java进程内存会一直增长。 3.如果加载附件中test2的dll(需要安装C++运行环境vcredist_x86),Java进程内存正常,不会一直增长。 dll说明: dll的工程源码在附件中,test1和test2的区别只在于编译选项,如附件:test1选择的是“使用标准Windows库”或“在静态库中使用MFC”,test2选择的是“在共享DLL中使用MFC” 此dll工程的特点在于使用了jni,并引入了mfc头文件【#include <afxwin.h>】,如果不引入mfc头文件则不会引起内存泄漏 目前此问题的根本原因尚不明确,怀疑是jdk的bug(使用最新的jdk1.6.0.23也没用),不知道大家有什么想法吗?欢迎大家讨论~ 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-06-20
dll里面是否有泄漏?
|
|
返回顶楼 | |
发表时间:2011-06-20
应该是dll的问题吧,我们项目用的在调试时也是总内存泄漏,后来他们改了下就好了!
|
|
返回顶楼 | |
发表时间:2011-06-20
谢谢各位的关注
我也知道是dll的问题 而且实验结果很明确 引用 2.如果加载附件中test1的dll,Java进程内存会一直增长。 3.如果加载附件中test2的dll(需要安装C++运行环境vcredist_x86),Java进程内存正常,不会一直增长。 引用 test1和test2的区别只在于编译选项,如附件:test1选择的是“使用标准Windows库”或“在静态库中使用MFC”,test2选择的是“在共享DLL中使用MFC” 但是还是不知道为什么会这样 |
|
返回顶楼 | |
发表时间:2011-06-21
最后修改:2011-06-21
> Java加载dll,导致Java进程内存泄露
请问进程是退出了,还是怎么抛出了异常? > 注:线程池只是为了加速问题复现,无其他用处。 这里问题大了,这是加速栈溢出,最终导致内存异常! |
|
返回顶楼 | |
发表时间:2011-06-21
C这边生成的资源,比如字符串什么的有没有回收?
|
|
返回顶楼 | |
发表时间:2011-06-21
david.org 写道 > Java加载dll,导致Java进程内存泄露
请问进程是退出了,还是怎么抛出了异常? > 注:线程池只是为了加速问题复现,无其他用处。 这里问题大了,这是加速栈溢出,最终导致内存异常! 原帖中说了 这个泄露指"Java进程内存会一直增长" |
|
返回顶楼 | |
发表时间:2011-06-22
应该是和DLL有关系。采用JNI开发了诸多连接程序,并没有发现此类问题
|
|
返回顶楼 | |
发表时间:2011-06-22
JVM动态加载的DLL归属于系统进程级别的管理,而DLL的内存资源是自己管理但与进程挂钩。
所以当你的test1.dll的内部内存不断增长而又不释放的话,进程的内存资源会不断增加。但并不影响JVM管理范围内的内存。 |
|
返回顶楼 | |
发表时间:2011-06-22
test1选择的是“使用标准Windows库”或“在静态库中使用MFC”
你看下这里面在引用别的DLL时,最后有没释放。如果有释放的话,试着将线程的时间设置长一点,时间太短了,可能静态引用完成后,还没释放,你就再次加载DLL,从而造成内存不断增长。 test2选择的是“在共享DLL中使用MFC” 如果是共享的话,在加载时先判断内存里面是否有加载,如果有加载,就直接引用,就不会存在一直增长。 |
|
返回顶楼 | |