2011-08-08 5 views
2

Il semble que le code suivant fuit la mémoire. J'ai vérifié l'utilisation de la mémoire JVM et il ne libère pas de mémoire après les appels suivants. Lorsque je lance le Java en mode autonome, il fonctionne correctement pour plusieurs appels et permet de libérer la mémoire correctement.Java JNI de fuite de mémoire C

J'apprécierais vraiment toute aide.

jobjectArray my_obj = (jobjectArray) env->CallObjectMethod(cls, mid, qstr, pstr); 

length = env->GetArrayLength(my_obj); 
//printf("\nArray Length = %d \n", length); 

char result[256]; 
const char *cstr; 
int numberOfCharsInThisRow = 0; 


array1 = (char **)malloc(length * sizeof(char *)); 
/*Check if pointer is null, if not then free its memory first*/ 

for(int i=0; i< length ; i++){ 
    cstr = env->GetStringUTFChars((jstring)env->GetObjectArrayElement(my_obj,i), 0); 

    numberOfCharsInThisRow = std::strlen(cstr)+1; 


    *(array1+i)=(char *)malloc(numberOfCharsInThisRow * sizeof(char)); 

    std::strcpy(result, cstr); 
    std::strcpy(*(array1+i),result); 


    env->ReleaseStringUTFChars((jstring)env->GetObjectArrayElement(my_obj,i), cstr); 
     } 
    env->DeleteLocalRef(my_obj); 
} 

    //printf("\n\nDestroy JVM\n\n"); 
    //jvm->DestroyJavaVM(); 

} 

libdeallocatememory vide (char ** array1, longueur int) { // printf ("mémoire Array libre \ n");

for (int j=0 ;j <length ;j ++) 
{ 
    free(array1+j); 
} 

free(array1); 

}

+0

Je suppose que vous libérez les pointeurs vous avez attribués à un certain moment et ce nest pas la fuite que vous parlez – jogabonito

+0

Bonjour, pas il n'y a pas d'appels à libérer les pointeurs, ISNT ReleaseStringUTFChars et DeleteLocalRef s'en occupent? J'apprécierais si vous me direz s'il vous plaît quels pointeurs j'ai besoin de libérer – ShamsR

Répondre

1

Vous devez libérer les pointeurs Array1 une fois que vous avez terminé avec eux. Que fait cette fonction en réalité? De la fonctionnalité que j'ai comprise, vous copiez du java à un pointeur c. Qu'est-ce qui se passe ensuite? En appelant ReleaseStringUTF, vous notifiez la JVM qu'elle n'est pas utilisée en natif et que vous pouvez ainsi la générer en cas de besoin.
Pensez que j'ai trouvé le problème. Releasing Code devrait être quelque chose comme

for (int j=0 ;j<length; j++ ) 
{ 
    free(array1[j]); 
} 

free(array1); 

L'allocation initiale devrait être array1 = (char **)malloc(length * sizeof(int *));
La différence est int* au lieu de char*. C'est parce que ce tableau est juste un tableau de pointeurs. La taille du pointeur est int. Le niveau suivant est dans la boucle où vous allouez de la mémoire pour vos chaînes. Cela devrait être array1[i] = (char *)malloc(numberOfCharsInThisRow * sizeof(char));
Cela signifie initialement que vous avez alloué un tableau de pointeurs. Maintenant, pour chaque élément de cet arary, vous allouez la mémoire pour contenir sa propre chaîne. Je pense que même *(array1+i) fonctionnera, mais je trouve cela plus facile à lire. Ainsi, lorsque vous êtes libre, vous libérez d'abord les éléments de tableau individuels que vous avez alloués, puis le tableau entier que vous avez initialement attribué. A titre d'exemple, jetez un oeil à votre fonction deallocate actuelle. Il n'y a pas de différence entre le gratuit quand j = 0 et le dernier gratuit. Je suis surpris que vous n'ayez pas de crash.
Jetez un oeil à http://c-faq.com/~scs/cclass/int/sx9b.html

Essayez aussi le jstring myString =env->GetObjectArrayElement(my_obj,i) suivant; Utilisez myString pour obtenir les UTFChars, appelez ensuite env->ReleaseStringUTFChars(mystring, cstr)

+0

Salut, array1 est libéré après qu'il soit utilisé. Voici comment array1 est en train d'être libéré. La fonction est un wrapper à une méthode Java qui renvoie le résultat d'un appel SQL en tant que tableau. – ShamsR

+1

Bonjour, array1 est en cours de libération après son utilisation. Voici comment est libéré array1 J'ai édité le post principal. La fonction est un wrapper à une méthode Java qui renvoie le résultat d'un appel SQL en tant que tableau. Ce que nous avons remarqué que si nous supprimons l'appel de mallocing array1, cela augmente encore la taille du tas JVM, ce qui nous amène à penser que ReleaseStringUTF ne libère pas de mémoire. J'apprécierais toute aide – ShamsR

+0

Bonjour, je libère le array1 comme vous l'avez mentionné, le problème persiste encore, je me demande si cela a à voir avec ReleaseStringUTF ne libérant pas la mémoire ou la façon dont nous copions sur c pointeur a des problèmes. – ShamsR