Утечка Java JNI в процессе c ++ - PullRequest
5 голосов
/ 16 марта 2011

Я новичок в Java. Моя проблема: я вызываю метод класса Java из c ++. Для этого я использую JNI. Все работает правильно, но у меня есть некоторые УТЕЧКИ памяти в процессе программы 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 МБ памяти

4) Затем я удаляю класс, объект и Java-машину.

В этот самый момент 10 МБ памяти не свободны ................. Так что ниже у меня есть несколько строк кода

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-класс (он просто выделяет память)

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 ++.

НЕКОТОРЫЕ РЕДАКТИРОВАТЬ ....

если я выделю новую память (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])

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

1 Ответ

3 голосов
/ 16 марта 2011

Это нормальное поведение. Память будет использоваться повторно, если вы выполняете какие-то другие операции в вашем процессе, но она не возвращается в ОС как свободная память по соображениям производительности. У вас нет утечки памяти, так как эта память не потеряна, но она может использоваться только вашим процессом (конечно, пока он не завершится).

...