2011-03-16 40 views
5

我是Java初學者。我的問題是:我從C++調用Java類的方法。爲此,我使用JNI。逝去的工作是正確的,但我在C++程序的過程中的一些內存泄漏...C++進程中的Java JNI泄漏

所以..我做了簡單的例子..

1)我創建一個Java機(jint RES = JNI_CreateJavaVM(& JVM,(無效**)&的env,& vm_args);)

2)然後我需要一個指針上java類(JCLASS CLS = env-> findClass的( 「test_jni」));

3)之後,我創建一個Java類對象的對象,通過調用構造(testJavaObject = env-> NewObject的(CLS,testConstruct);)

AT在C的過程此時此刻++程序被分配10 MB的內存

4)接下來,我刪除了類,對象,和Java機..

在這個非常時刻的10 MB的內存是不是免費的 ........ ......... 所以下面我有幾行代碼

C++程序

void main() 
{ 
    { 
     //Env 
     JNIEnv *env; 
     // java virtual machine 
     JavaVM *jvm; 
     JavaVMOption* options = new JavaVMOption[1]; 
     //class paths 
     options[0].optionString = "-Djava.class.path=C:/Sun/SDK/jdk/lib;D:/jms_test/java_jni_leak;"; 
     // other options 
     JavaVMInitArgs vm_args; 
     vm_args.version = JNI_VERSION_1_6; 
     vm_args.options = options; 
     vm_args.nOptions = 1; 
     vm_args.ignoreUnrecognized = false; 
     // alloc part of memory (for test) before CreateJavaVM 
     char* testMem0 = new char[1000]; 
     for(int i = 0; i < 1000; ++i) 
      testMem0[i] = 'a'; 
     // create java VM 
     jint res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); 
     // alloc part of memory (for test) after CreateJavaVM 
     char* testMem1 = new char[1000]; 
     for(int i = 0; i < 1000; ++i) 
      testMem1[i] = 'b'; 
     //Creating java virtual machine 
     jclass cls = env->FindClass("test_jni"); 
     // Id of a class constructor 
     jmethodID testConstruct = env->GetMethodID(cls, "<init>", "()V"); 
     // The Java Object 
     // Calling the constructor, is allocated 10 MB of memory in c++ process 
     jobject testJavaObject = env->NewObject(cls, testConstruct); 
     // function DeleteLocalRef, 
     // In this very moment memory not free 
     env->DeleteLocalRef(testJavaObject); 
     env->DeleteLocalRef(cls); 
     // 1!!!!!!!!!!!!! 
     res = jvm->DestroyJavaVM(); 
     delete[] testMem0; 
     delete[] testMem1; 
     // In this very moment memory not free. TO /// 
    } 
    int gg = 0; 
} 

java類(它只是allocs一些存儲器)

import java.util.*; 

public class test_jni 
{ 
    ArrayList<String> testStringList; 
    test_jni() 
    { 
    System.out.println("start constructor"); 
    testStringList = new ArrayList<String>(); 
    for(int i = 0; i < 1000000; ++i) 
    { 
     // засераю память 
     testStringList.add("TEEEEEEEEEEEEEEEEST"); 
    } 
    } 
} 

進程內存視圖,板條箱的JavaVM和Java對象後: testMem0和testMem1 - 測試存儲器,這是被C分配++ 。

************** 
testMem0 
************** 




JNI_CreateJavaVM 




************** 
testMem1 
************** 

// create java object 
jobject testJavaObject = env->NewObject(cls, testConstruct); 

************** 

進程內存視圖,後破壞JAVAVM和刪除Java對象的參照: testMem0和testMem1被刪除到;

************** 




JNI_CreateJavaVM 




************** 

// create java object 
    jobject testJavaObject = env->NewObject(cls, testConstruct); 

************** 

所以testMem0和testMem1被刪除,但JavaVM的和 Java對象不是....

母豬我做錯了...以及如何我可以釋放在C++程序的程序存儲器的內容。

SOME EDIT ....

如果我ALLOC新存儲器(字符* TEST3 =新的char [1000]),破壞JVM,C的堆之後++過程看起來喜歡這樣:

和存儲器過程正在成長!...

************** 




JNI_CreateJavaVM (memory after JVM) 




************** 

jobject testJavaObject = env->NewObject(cls, testConstruct); 
memory after Java object 


************** 

char* test3 (memory is allocated by char* test3 = new char[1000]) 

************** 
+0

只是好奇:你如何檢查空閒內存? – bestsss 2011-03-16 08:14:04

+0

我在任務管理器中查看內存大小,然後在heapviewer – DimShust 2011-03-16 12:31:12

+0

的內存中查看該情況,我認爲這是正常行爲;它會發生在您添加的任何其他庫上。除了堆之外,還有代碼要加載。只是B/C沒有實例,並不意味着整個代碼都在吹。如果內存對於虛擬機的每個alloc/dealloc都保持上升,則會發生泄漏。 – bestsss 2011-03-16 12:45:58

回答

3

這是正常行爲。如果在進程中執行其他分配,內存將被重用,但由於性能原因,它不會作爲可用內存返回到操作系統。 您沒有內存泄漏,因爲此內存不會丟失,但它只能由您的進程重用(直到它退出課程)。

+0

我已經做了一些第一篇文章的編輯,所以如果我分配內存,在破壞Java VM之後,進程的內存正在增長...... – DimShust 2011-03-16 10:39:50