Java加載dll,導(dǎo)致Java進(jìn)程內(nèi)存泄露
By zhaoch在做網(wǎng)絡(luò)監(jiān)控系統(tǒng)的性能測(cè)試時(shí),出現(xiàn)了內(nèi)存泄露的問(wèn)題,困擾了很久,現(xiàn)在終于算是解決了,但是根本原因尚不明確,拿出來(lái)大家討論下,看看能不能完美解決~
這個(gè)問(wèn)題奇怪的地方在于是Java進(jìn)程內(nèi)存泄露,而不是平常的JVM內(nèi)存泄露,用Jprofile等工具也無(wú)法看出問(wèn)題所在。
測(cè)試代碼如下:
這個(gè)問(wèn)題奇怪的地方在于是Java進(jìn)程內(nèi)存泄露,而不是平常的JVM內(nèi)存泄露,用Jprofile等工具也無(wú)法看出問(wèn)題所在。
測(cè)試代碼如下:
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 }
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 }
注:線程池只是為了加速問(wèn)題復(fù)現(xiàn),無(wú)其他用處。
現(xiàn)象:
1.如果不加載dll,只不斷的啟動(dòng)線程,Java進(jìn)程內(nèi)存正常,不會(huì)一直增長(zhǎng)。
2.如果加載附件中test1的dll,Java進(jìn)程內(nèi)存會(huì)一直增長(zhǎng)。
3.如果加載附件中test2的dll(需要安裝C++運(yùn)行環(huán)境vcredist_x86),Java進(jìn)程內(nèi)存正常,不會(huì)一直增長(zhǎng)。
dll說(shuō)明:
dll的工程源碼在附件中,test1和test2的區(qū)別只在于編譯選項(xiàng),如附件:test1選擇的是“使用標(biāo)準(zhǔn)Windows庫(kù)”或“在靜態(tài)庫(kù)中使用MFC”,test2選擇的是“在共享DLL中使用MFC”
此dll工程的特點(diǎn)在于使用了jni,并引入了mfc頭文件【#include <afxwin.h>】,如果不引入mfc頭文件則不會(huì)引起內(nèi)存泄漏
目前此問(wèn)題的根本原因尚不明確,懷疑是jdk的bug(使用最新的jdk1.6.0.23也沒(méi)用),不知道大家有什么想法嗎?歡迎大家討論~
/Files/cyj86/dll工程.rar
/Files/cyj86/test1.rar
/Files/cyj86/test2.rar
/Files/cyj86/vcredist_x86.rar
/Files/cyj86/opt.png

posted on 2011-06-13 11:45 薛定諤的貓 閱讀(1788) 評(píng)論(4) 編輯 收藏 所屬分類(lèi): 典型、疑難問(wèn)題