论坛首页 Java企业应用论坛

Java加载dll,导致Java进程内存泄露

浏览 13268 次
精华帖 (0) :: 良好帖 (2) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-06-20  
By zhaoch
在做网络监控系统的性能测试时,出现了内存泄露的问题,困扰了很久,现在终于算是解决了,但是根本原因尚不明确,拿出来大家讨论下,看看能不能完美解决~

这个问题奇怪的地方在于是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也没用),不知道大家有什么想法吗?欢迎大家讨论~



  • 大小: 22.5 KB
   发表时间:2011-06-20  
dll里面是否有泄漏?
0 请登录后投票
   发表时间:2011-06-20  
应该是dll的问题吧,我们项目用的在调试时也是总内存泄漏,后来他们改了下就好了!
0 请登录后投票
   发表时间:2011-06-20  
谢谢各位的关注
我也知道是dll的问题
而且实验结果很明确
引用

2.如果加载附件中test1的dll,Java进程内存会一直增长。
3.如果加载附件中test2的dll(需要安装C++运行环境vcredist_x86),Java进程内存正常,不会一直增长。

引用

test1和test2的区别只在于编译选项,如附件:test1选择的是“使用标准Windows库”或“在静态库中使用MFC”,test2选择的是“在共享DLL中使用MFC”

但是还是不知道为什么会这样
0 请登录后投票
   发表时间:2011-06-21   最后修改:2011-06-21
> Java加载dll,导致Java进程内存泄露

请问进程是退出了,还是怎么抛出了异常?


> 注:线程池只是为了加速问题复现,无其他用处。

这里问题大了,这是加速栈溢出,最终导致内存异常!
0 请登录后投票
   发表时间:2011-06-21  
C这边生成的资源,比如字符串什么的有没有回收?
0 请登录后投票
   发表时间:2011-06-21  
david.org 写道
> Java加载dll,导致Java进程内存泄露

请问进程是退出了,还是怎么抛出了异常?


> 注:线程池只是为了加速问题复现,无其他用处。

这里问题大了,这是加速栈溢出,最终导致内存异常!


原帖中说了 这个泄露指"Java进程内存会一直增长"
0 请登录后投票
   发表时间:2011-06-22  
应该是和DLL有关系。采用JNI开发了诸多连接程序,并没有发现此类问题
0 请登录后投票
   发表时间:2011-06-22  
JVM动态加载的DLL归属于系统进程级别的管理,而DLL的内存资源是自己管理但与进程挂钩。

所以当你的test1.dll的内部内存不断增长而又不释放的话,进程的内存资源会不断增加。但并不影响JVM管理范围内的内存。
0 请登录后投票
   发表时间:2011-06-22  
test1选择的是“使用标准Windows库”或“在静态库中使用MFC”

你看下这里面在引用别的DLL时,最后有没释放。如果有释放的话,试着将线程的时间设置长一点,时间太短了,可能静态引用完成后,还没释放,你就再次加载DLL,从而造成内存不断增长。

test2选择的是“在共享DLL中使用MFC”

如果是共享的话,在加载时先判断内存里面是否有加载,如果有加载,就直接引用,就不会存在一直增长。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics