问题描述:

I create a byte array in java and pass it by reference to the jni function. This I do in a loop and and sometimes get a out of memory error in the jni. I wanted to know if java automatically frees the array on every iteration or since it is passed to the jni function, it doesn't ??

JNI Code (bOldArray is the java byte array that i pass to jni as an argument)

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

网友答案:

you have 2 buffers here, one handed from your java code (bOldArray)and the local buffer (oldbuff) which you allocated in line 2.

in fact, you might have more buffers, because

(*env)->GetArrayLength 

with almost certainly makes a unmovable copy of the memory (needed for c-pointer-access), which holds the array in you java code and with

(*env)->ReleaseByteArrayElements(env,bOldArray,(jbyte *)bytes,0);

this memory is copied back onto the memory of your java array (check documentation of the last argument of ReleaseByteArrayElements)

but about you problem: you should free oldBuff too.

free(oldBuff);

else the VM does free your c-copy of the java array but not the self-allocated part directly (it might do thiz later due to object-lifetime and garbage collection, but this is unpredictable and therefore the out-of-memory error is also unpredictable)

to avoid the java-c-copy mechanism (speeds up performance) use a shared/static buffer like ByteBuffer

网友答案:

If you are using GetByteArrayElements you have to call ReleaseByteArrayElements after you are done with the array in JNI, because the JVM will prevent the freeing of this array in java until you do so. Please post the code to get a clearer idea

相关阅读:
Top