2011-03-16 13 views
5

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

************** 
+0

Sólo curiosidad: ¿cómo se comprueba la memoria libre? – bestsss

+0

busco en el tamaño de la memoria en el administrador de tareas y busco en la memoria en heapviewer – DimShust

+0

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

Respuesta

3

Esto es comportamiento normal. La memoria se reutilizará si realiza otras asignaciones en el proceso, pero no se devuelve como memoria libre al sistema operativo por motivos de rendimiento. No tiene una pérdida de memoria ya que esta memoria no se pierde, pero solo puede ser reutilizada por su proceso (hasta que finalice, por supuesto).

+0

He hecho algunas ediciones de la primera publicación, así que si aloco memoria, después de destruir Java VM, la memoria del proceso está creciendo ... – DimShust

Cuestiones relacionadas