2011-03-16 54 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