Je suis débutant en Java. Mon problème est: J'appelle la méthode d'une classe Java de C++. Pour cela, j'utilise JNI. Everythings fonctionne correctement, mais j'ai quelques Fuites de mémoire dans le processus de C++ programme ...Java JNI fuite dans le processus C++
.. Alors je l'ai fait exemple simple ..
1) Je crée une machine java (JINT res = JNI_CreateJavaVM (& JVM (void **) & env, & vm_args);)
2) puis-je prendre un pointeur sur la classe Java (JClass cls = env-> FindClass ("test_jni"));
3) après que je crée un objet de l'objet de classe Java, en appelant le constructeur (testJavaObject = env-> NewObject (cls, testConstruct);)
à ce moment dans le processus de programme C++ est alloué 10 Mo de mémoire
4) Ensuite je supprimer la classe, l'objet et la machine Java ..
en ce moment les 10 Mo de mémoire ne sont pas libres ........ ......... Donc, ci-dessous j'ai quelques lignes de code
C++ programme
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;
}
classe java (il Alloue juste un peu de mémoire)
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");
}
}
}
vue mémoire du processus, après la mise en caisse javavm et objet java: testMem0 et testMem1 - Test de mémoire, c'est alloué par C++ .
**************
testMem0
**************
JNI_CreateJavaVM
**************
testMem1
**************
// create java object
jobject testJavaObject = env->NewObject(cls, testConstruct);
**************
vue en mémoire du processus
, détruire après JavaVM et supprimer ref sur l'objet Java: testMem0 et testMem1 sont supprimés à;
**************
JNI_CreateJavaVM
**************
// create java object
jobject testJavaObject = env->NewObject(cls, testConstruct);
**************
Alors testMem0 et testMem1 est supprimé, mais JavaVM et objet Java ne ....
Sow ce que je fais mal ... et comment je peux libérer de la mémoire dans le C++ programme de processus.
QUELQUES EDIT ....
si j'alloc nouvelle mémoire (char * test3 = new char [1000]), après avoir détruit JVM, tas de C++ processus ressemble donc aime:
et la mémoire le processus grandit! ...
**************
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])
**************
Juste curieux: comment vérifiez-vous la mémoire libre? – bestsss
je regarde la taille de la mémoire dans le gestionnaire de tâches et je regarde la mémoire dans heapviewer – DimShust
dans ce cas, je considère comme un comportement normal; cela arrivera w/toute autre bibliothèque que vous ajoutez.Outre le tas, il y a du code à charger. Juste b/c il n'y a pas d'instances, cela ne signifie pas que le code entier va bouffer. La fuite serait si la mémoire continue à augmenter pour chaque alloc/dealloc d'une machine virtuelle. – bestsss