我在java中创建一个字节数组,并通过引用jni函数传递它。我在循环中执行此操作,有时会在jni中出现内存不足错误。我想知道java是否在每次迭代时自动释放数组,或者因为它被传递给jni函数,它不会??
JNI代码(bOldArray是我传递给jni作为参数的java字节数组)
len = (*env)->GetArrayLength(env,bOldArray);
char *oldBuff = (char *)calloc(sizeof(char),MAX_SIZE);
jbyte* bytes = (*env)->GetByteArrayElements(env,bOldArray,0);
memcpy(oldBuff,bytes,len);
(*env)->ReleaseByteArrayElements(env,bOldArray,(jbyte *)bytes,0);
答案 0 :(得分:2)
这里有2个缓冲区,一个来自你的java代码(bOldArray)和你在第2行分配的本地缓冲区(oldbuff)。
实际上,你可能有更多的缓冲区,因为
(*env)->GetArrayLength
几乎可以肯定地制作了一个不可移动的内存副本(c-pointer-access所需),它将数组保存在你的java代码中并且带有
(*env)->ReleaseByteArrayElements(env,bOldArray,(jbyte *)bytes,0);
将此内存复制回java数组的内存(查看ReleaseByteArrayElements最后一个参数的文档)
但关于你的问题:你也应该释放oldBuff。
free(oldBuff);
否则VM会释放你的java数组的c副本而不是直接释放自我分配的部分(由于对象生命周期和垃圾收集,它可能会稍后发布,但这是不可预测的,因此不可预测内存错误也是不可预测的)
避免java-c-copy机制(加快性能)使用像ByteBuffer这样的共享/静态缓冲区
答案 1 :(得分:0)
如果您正在使用GetByteArrayElements
,则必须在完成JNI中的数组后调用ReleaseByteArrayElements
,因为JVM将阻止在java中释放此数组,直到您这样做为止。
请发布代码以获得更清晰的想法