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])
**************
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With