读书人

Java加载dll以致Java进程内存泄露

发布时间: 2012-12-24 10:43:13 作者: rapoo

Java加载dll,导致Java进程内存泄露
在做网络监控系统的性能测试时,出现了内存泄露的问题,困扰了很久,现在终于算是解决了,但是根本原因尚不明确,拿出来大家讨论下,看看能不能完美解决~

这个问题奇怪的地方在于是Java进程内存泄露,而不是平常的JVM内存泄露,用Jprofile等工具也无法看出问题所在。

测试代码如下:

?1?System.loadLibrary("test1");
?2?
?3?????????int?threadPoolSize?=?400;
?4?????????ExecutorService?service?=?Executors.newFixedThreadPool(threadPoolSize);
?5?
?6?????????for?(int?i?=?0;?i?<?400;?i++)?{
?7?????????????service.submit(new?Runnable()?{
?8?????????????????public?void?run()?{
?9?????????????????????while?(true)?{
10?????????????????????????try?{
11?????????????????????????????Thread?t?=?new?Thread();
12?????????????????????????????t.start();
13?????????????????????????????Thread.sleep(100);
14?????????????????????????}?catch?(Exception?e)?{
15?????????????????????????????e.printStackTrace();
16?????????????????????????}
17?????????????????????}
18?????????????????}
19?????????????});
20?????????}

?

说明:此段代码所做的工作就是加载一个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也没用),不知道大家有什么想法吗?欢迎大家讨论~

/Files/cyj86/dll工程.rar
/Files/cyj86/test1.rar
/Files/cyj86/test2.rar
/Files/cyj86/vcredist_x86.rar
/Files/cyj86/opt.pngJava加载dll,以致Java进程内存泄露

1 楼 langyu 2011-06-15 如果你确定是因为load test1 dll有内存泄露,那么后面一段程序就会有影响你判断的嫌疑。单把后面一段程序拉出来运行,因为频繁地创建和销毁线程,GC忙不过来的时候就会有少量内存增长的问题,但不会长时间显现。所以如果你肯定是因为dll的问题,那么单独执行loadLibary,而不要后面的这部分,再来确定下是否真是JNI的问题。

附件在哪儿?

PS:到现在为至,程序执行了近五分钟,内存还在不断地少量增加。我怀疑是你的初衷是想让程序一直运行来测试JNI,但后面这部分线程让问题复杂化了。内存增长仅仅是来自于JNI么?

读书人网 >编程

热点推荐