Soy principiante en Java. Mi problema es: estoy llamando a un método de la clase Java desde C++. Para esto estoy usando JNI. Everythings funciona correctamente, pero tengo algunas pérdidas de memoria en el proceso de programa en C++ ...Fuga de Java JNI en el proceso C++
Así que .. lo hice ejemplo sencillo ..
1) que crea una máquina Java (jint res = JNI_CreateJavaVM (& JVM, (void **) & env, & vm_args);)
2) entonces tomo un puntero de clase java (jClass cls = env> FindClass ("test_jni"));
3) después de que i crear un objeto de clase de objeto java, llamando al constructor (testJavaObject = env-> NewObject (cls, testConstruct);)
en este mismo momento en el proceso de programa en C++ se asigna 10 MB de memoria
4) A continuación borro la clase, el objeto y la máquina de Java ..
en este mismo momento los 10 MB de memoria no están libres ........ ......... Así que abajo tengo unas líneas de código
programa en 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;
}
clase Java (sólo allocs parte de la memoria)
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");
}
}
}
proceso de vista de la memoria, después de encajonamiento JavaVM y el objeto java: testMem0 y testMem1 - prueba de memoria, eso es asignado por C++ .
**************
testMem0
**************
JNI_CreateJavaVM
**************
testMem1
**************
// create java object
jobject testJavaObject = env->NewObject(cls, testConstruct);
**************
proceso de vista de la memoria, después de destruir y eliminar JavaVM ref en el objeto java: testMem0 y testMem1 se eliminan a;
**************
JNI_CreateJavaVM
**************
// create java object
jobject testJavaObject = env->NewObject(cls, testConstruct);
**************
Así testMem0 y testMem1 se borran, pero JavaVM y Java no se oponen ....
Sow lo que hago mal ... y cómo puedo liberar memoria en el programa de proceso de C++.
ALGUNAS EDITAR ....
si alloc nueva memoria (char * test3 = new char [1000]), después de destruir JVM, montón de C++ parece proceso le gusta por lo que:
Y la memoria de proceso está creciendo! ...
**************
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])
**************
Sólo curiosidad: ¿cómo se comprueba la memoria libre? – bestsss
busco en el tamaño de la memoria en el administrador de tareas y busco en la memoria en heapviewer – DimShust
en ese caso lo considero un comportamiento normal; sucederá con cualquier otra biblioteca que agregue.Además del montón, hay código para ser cargado. Solo porque no hay instancias, no significa que todo el código se está volviendo inflado. La fuga sería si la memoria sigue aumentando para cada alloc/dealloc de una máquina virtual. – bestsss