JNI Java来自C内存泄漏

时间:2011-08-08 18:32:12

标签: java-native-interface

以下代码似乎正在泄漏内存。我检查了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(“Free Array memory \ n”);

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

free(array1);   

}

1 个答案:

答案 0 :(得分:1)

完成后,您应该释放array1指针。这个功能在现实中做了什么?从我理解的功能,你是从java复制到c指针。接下来发生什么?通过调用ReleaseStringUTF,您通知JVM它不是在本机中使用,因此可以在需要时进行GC操作  我想我发现了这个问题。发布代码应该是

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)也可以,但我发现这更容易阅读。因此,当您释放时,首先释放您分配的各个数组元素,然后释放最初分配的整个数组。举个例子,看一下你当前的deallocate函数。当j = 0和最后一个空闲时,free之间没有区别。我很惊讶你没有发生任何撞车事故 看看http://c-faq.com/~scs/cclass/int/sx9b.html

同时尝试以下jstring myString =env->GetObjectArrayElement(my_obj,i);使用myString获取UTFChars,然后调用env->ReleaseStringUTFChars(mystring, cstr)