Results 1 to 13 of 13
  1. #1
    Gigabitze is offline Member
    Join Date
    Feb 2011
    Posts
    7
    Rep Power
    0

    Default Java from c++ (JNI) memory leaks

    Hi all.. 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

    3) 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++ prgram:
    Java Code:
    #include <jni.h>
    
    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;
            // создаем виртуальную машину
            jint res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
            //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();
            // In this very moment memory not free. TO ///
        }
    }
    AND Java class

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

  2. #2
    Gigabitze is offline Member
    Join Date
    Feb 2011
    Posts
    7
    Rep Power
    0

    Default

    Ok i tested the code...

    so.. when i call res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
    allocating some memory... (res == 0)
    then:
    i call res = jvm->DestroyJavaVM();
    (res == 0)
    And memory is not deallocating... so why it is ?

  3. #3
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,733
    Blog Entries
    7
    Rep Power
    21

    Default

    The JVM does release its memory but it can't return it to the OS; the JVM and your C++ program run in the same process space (in a different thread most likely) but both subprocesses (C++ and the JVM) claim memory from the OS. After the JVM has released its memory it'll be available to your C++ part of the process.

    kind regards,

    Jos
    cenosillicaphobia: the fear for an empty beer glass

  4. #4
    Gigabitze is offline Member
    Join Date
    Feb 2011
    Posts
    7
    Rep Power
    0

    Default

    ok ... next simple test:
    In cycle i'm creating java object and trying to destroy it.... but i cant... so what is wrong
    i am doing so:
    Java Code:
    for(int i = 0; i < 100; ++i)
    {
       // call constructor
       // in this moment i am taking  +1MB
       jobject testJavaObject = env->NewObject(cls, testConstruct);
       env->DeleteLocalRef(testJavaObject);
       // after DeleteLocalRef memory are not deallocating.
    }
    // so after for() i am having + 100MB

  5. #5
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,733
    Blog Entries
    7
    Rep Power
    21

    Default

    Quote Originally Posted by Gigabitze View Post
    ok ... next simple test:
    In cycle i'm creating java object and trying to destroy it.... but i cant... so what is wrong
    i am doing so:
    Java Code:
    for(int i = 0; i < 100; ++i)
    {
       // call constructor
       // in this moment i am taking  +1MB
       jobject testJavaObject = env->NewObject(cls, testConstruct);
       env->DeleteLocalRef(testJavaObject);
       // after DeleteLocalRef memory are not deallocating.
    }
    // so after for() i am having + 100MB
    How did you check the amount of allocated memory? Did you ask the OS by using 'top' or similar. As I wrote above the memory isn't returned to the OS, it is just available for your process again. You probably don't want to go into the gory details of the brk() and sbrk() system calls.

    kind regards,

    Jos
    cenosillicaphobia: the fear for an empty beer glass

  6. #6
    Gigabitze is offline Member
    Join Date
    Feb 2011
    Posts
    7
    Rep Power
    0

    Default

    I checked the amount of allocated memory, by using task manager...
    So when i am doing env->NewObject(cls, testConstruct);
    In task manager, my program process is taking + 1MB.

    I understood, that the memory availabel for my process again... But i dont whant it :) .... I need free this memory... how can i do it ?

  7. #7
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,733
    Blog Entries
    7
    Rep Power
    21

    Default

    Quote Originally Posted by Gigabitze View Post
    I checked the amount of allocated memory, by using task manager...
    So when i am doing env->NewObject(cls, testConstruct);
    In task manager, my program process is taking + 1MB.

    I understood, that the memory availabel for my process again... But i dont whant it :) .... I need free this memory... how can i do it ?
    You have to be extremely careful here; the memory was originally obtained from the OS in a stack manner, i.e. more and more pages were claimed from the OS. The JVM (when it was still alive) did the same (it's the only way a process can obtain memory from the OS). When the JVM terminates a chunk of memory isn't needed anymore. If that chunk of memory is at the top of that 'stack' it can be returned to the OS, otherwise, the chunk obtained by the JVM was somewhere in the middle because your C++ part of the process had claimed more memory, nothing can be returned to the OS.

    kind regards,

    Jos
    cenosillicaphobia: the fear for an empty beer glass

  8. #8
    Gigabitze is offline Member
    Join Date
    Feb 2011
    Posts
    7
    Rep Power
    0

    Default

    So... sorry for me so noobi :)... But i cant understand, What i must do ?
    Other words... How i must free the memory from c++ process ?

  9. #9
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,733
    Blog Entries
    7
    Rep Power
    21

    Default

    Quote Originally Posted by Gigabitze View Post
    So... sorry for me so noobi :)... But i cant understand, What i must do ?
    Other words... How i must free the memory from c++ process ?
    The C++ heap (used by malloc/free new/delete) might've 'wrapped around' the chunk of memory previously taken by the JVM. If you're new to all this highly complex crapola, forget about it and let the memory be where it is.

    kind regards,

    Jos
    cenosillicaphobia: the fear for an empty beer glass

  10. #10
    Gigabitze is offline Member
    Join Date
    Feb 2011
    Posts
    7
    Rep Power
    0

    Default

    Ok... create thx, that u are helping me..
    But, can u give simple example (c++ code), how is it possible... (The C++ heap (used by malloc/free new/delete) might've 'wrapped around' the chunk of memory previously taken by the JVM.)

  11. #11
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,733
    Blog Entries
    7
    Rep Power
    21

    Default

    Quote Originally Posted by Gigabitze View Post
    Ok... create thx, that u are helping me..
    But, can u give simple example (c++ code), how is it possible... (The C++ heap (used by malloc/free new/delete) might've 'wrapped around' the chunk of memory previously taken by the JVM.)
    I can't do that; it all depends on the size of the initial C/C++ heap; let the following depict the initial C/C++ heap:

    Java Code:
    CCCCCCCCCC
    after the JVM has been installed by your C/C++ code the memory looks like this:

    Java Code:
    CCCCCCCCCCJJJJJJJJJJJJJJJJJJJJ
    where the Js denote the space taken by the JVM; now if C/C++ allocates a bunch of memory, it'll end up here:

    Java Code:
    AAAAAAAAAAJJJJJJJJJJJJJJJJJJJJ
    where the As denote the allocated C/C++ objects; if your C/C++ code wants to allocate more memory, it'll end up here:

    Java Code:
    AAAAAAAAAAJJJJJJJJJJJJJJJJJJJJAAAAAACCCC
    where the As on the right are the newly allocated memory and the Cs at the end are just some more memory obtained from the OS but (not yet) needed. Note that the part of memory taken by the JVM is 'embedded' in the memory taken by your C++/C part of the process and can't be returned to the OS. Only memory at the end of the process data space can be returned to the OS; there's nothing you can do about it without quite some sophisticated memory fiddling.

    kind regards,

    Jos
    Last edited by JosAH; 02-27-2011 at 02:55 PM. Reason: fixed a tag ...
    cenosillicaphobia: the fear for an empty beer glass

  12. #12
    Gigabitze is offline Member
    Join Date
    Feb 2011
    Posts
    7
    Rep Power
    0

    Default

    Ok.. thank you very much... I have understood this situation.. and will be think... how can i kill this leak

  13. #13
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,733
    Blog Entries
    7
    Rep Power
    21

    Default

    Quote Originally Posted by Gigabitze View Post
    Ok.. thank you very much... I have understood this situation.. and will be think... how can i kill this leak
    You might give the following scenario a try:

    1) start the C++ part of your process;
    2) allocate quite a large chunk of memory;
    3) start the JVM;
    4) free the chunk allocated in step 2)

    This way (if that chunk is large enough) no object will be allocated beyond the position where the JVM is allocated. When the JVM is freed you can safely get rid (i.e. return to the OS) the memory previously taken by the JVM. It requires a bit of experimenting.

    kind regards,

    Jos
    cenosillicaphobia: the fear for an empty beer glass

Similar Threads

  1. memory leaks in Java
    By Navatha in forum New To Java
    Replies: 8
    Last Post: 09-29-2010, 07:42 PM
  2. Replies: 2
    Last Post: 08-21-2008, 08:33 PM
  3. Axis 1.4 xerces memory leaks
    By hlaprade in forum Advanced Java
    Replies: 0
    Last Post: 12-11-2007, 01:42 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •