Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java JNI leak in c++ process

I am beginner in Java. My problem is: I am calling a Java class's method from c++. For this i am using JNI. Everythings works correct, but i have some memory LEAKS in the process of c++ program...

So.. i did simple example..

1) I create a java machine (jint res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);)

2) then i take a pointer on java class (jclass cls = env->FindClass("test_jni"));

3) after that i create a java class object object, by calling the constructor (testJavaObject = env->NewObject(cls, testConstruct);)

AT THIS very moment in the process of c++ program is allocated 10 MB of memory

4) Next i delete the class , the object, and the Java Machine ..

AT THIS very moment the 10 MB of memory are not free ................. So below i have a few lines of code

c++ program

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 class (it just allocs some memory)

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");
    }
  }
}

process memory view, after crating javaVM and java object: testMem0 and testMem1 - test memory, that's allocated by c++.

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




JNI_CreateJavaVM




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

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

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

process memory view, after destroy javaVM and delete ref on java object: testMem0 and testMem1 are deleted to;

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




JNI_CreateJavaVM




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

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

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

So testMem0 and testMem1 is deleted, But JavaVM and Java object not....

Sow what i do wrong... and how i can free memory in the c++ process program.

SOME EDIT....

if i alloc new memory (char* test3 = new char[1000]), after destroying JVM, heap of c++ process looks likes so:

And memory of process is growing up !...

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




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])

**************
like image 491
BoberCoder Avatar asked Oct 11 '22 12:10

BoberCoder


1 Answers

This is normal behaviour. The memory will be reused if you do some other allocations in your process, but it is not returned as free memory to the OS for performance reasons. You don't have a memory leak as this memory is not lost, but it can only be reused by your process (until it exits of course).

like image 136
Benoit Thiery Avatar answered Oct 17 '22 04:10

Benoit Thiery