Java JNI在c ++进程中泄漏

Bob*_*der 5 c c++ java memory java-native-interface

我是Java的初学者.我的问题是:我从c ++调用Java类的方法.为此,我正在使用JNI.Everythings工作正常,但我在c ++程序的过程中有一些内存泄漏......

所以..我做了一个简单的例子..

1)我创建了一个java机器(jint res = JNI_CreateJavaVM(&jvm,(void**)&env,&vm_args);)

2)然后我在java类上使用指针(jclass cls = env-> FindClass("test_jni"));

3)之后我通过调用构造函数创建一个java类对象对象(testJavaObject = env-> NewObject(cls,testConstruct);)

此时此刻在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;
}
Run Code Online (Sandbox Code Playgroud)

java类(它只是分配一些内存)

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");
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

进程内存视图,在创建javaVM和java对象之后:testMem0和testMem1 - 测试内存,由c ++分配.

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




JNI_CreateJavaVM




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

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

**************
Run Code Online (Sandbox Code Playgroud)

进程内存视图,破解javaVM并删除java对象的ref:testMem0和testMem1被删除;

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




JNI_CreateJavaVM




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

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

**************
Run Code Online (Sandbox Code Playgroud)

所以testMem0和testMem1被删除了,但是JavaVM和Java对象没有....

播下我做错了什么......以及如何在c ++过程程序中释放内存.

一些编辑....

如果我分配新的内存(char*test3 = new 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])

**************
Run Code Online (Sandbox Code Playgroud)

Ben*_*ery 4

这是正常行为。如果您在进程中进行其他一些分配,内存将被重用,但出于性能原因,它不会作为可用内存返回给操作系统。您没有内存泄漏,因为该内存不会丢失,但它只能由您的进程重用(当然直到它退出)。