JNI Java из C утечки памяти - PullRequest
       15

JNI Java из C утечки памяти

2 голосов
/ 08 августа 2011

Кажется, что следующий код утечка памяти. Я проверил использование памяти JVM, и оно не освобождает память после последующих вызовов. Когда я просто запускаю Java в автономном режиме, он отлично работает для нескольких вызовов и просто освобождает память.

Я был бы очень признателен за любую помощь.

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();

}

void libdeallocatememory (char ** array1, int length) { // printf ("Свободная память массива \ n");

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

free(array1);   

}

1 Ответ

1 голос
/ 09 августа 2011

Вы должны освободить указатели array1, как только закончите с ними.Что эта функция делает в реальности?Из функциональности, которую я понял, вы копируете из Java в AC-указатель.Что происходит дальше?Вызывая ReleaseStringUTF, вы уведомляете JVM о том, что он не используется в нативном режиме и поэтому может быть GCed при необходимости
Думаю, я обнаружил проблему.Выпуск кода должен быть примерно таким:

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

free(array1);  

Первоначальное распределение должно быть array1 = (char **)malloc(length * sizeof(int *));
Разница составляет int* вместо char*.Это потому, что этот массив является просто массивом указателей.Размер указателя int.Следующий уровень находится в цикле, где вы выделяете память для ваших строк.Это должно быть array1[i] = (char *)malloc(numberOfCharsInThisRow * sizeof(char));
Это означает, что изначально вы выделили массив указателей.Теперь для каждого элемента этой статьи вы выделяете память для хранения своей собственной строки.Я думаю, что даже *(array1+i) будет работать, но я считаю, что это легче читать.Поэтому, когда вы освобождаете, сначала вы освобождаете отдельные элементы массива, которые вы разместили, а затем весь массив, который вы выделили изначально.Как пример, взгляните на вашу текущую функцию освобождения.Нет разницы между свободным при j = 0 и последним свободным.Я удивлен, что вы не получаете никаких сбоев.
Взгляните на http://c -faq.com / ~ scs / cclass / int / sx9b.html

Также попробуйтеследующий jstring myString =env->GetObjectArrayElement(my_obj,i);Используйте myString для получения UTFChars, затем вызовите env->ReleaseStringUTFChars(mystring, cstr)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...