Reputation: 13634
When I return a direct ByteBuffer to JNI, how long until it can get reclaimed by the JVM/GC?
Suppose I have a function like this:
void* func()
{
[ ... ]
jobject result = env->CallStaticObjectMethod(testClass, doSomethingMethod);
void* pointerToMemory = env->GetDirectBufferAddress(result);
return pointerToMemory;
}
The JVM can't possibly know how long I'm going to use that pointerToMemory
, right? What if I want to hold on to that address and the corresponding memory for a while?
Suppose I want to circumvent this issue and return a byte[] from Java to JNI like this:
ByteBuffer buf;
byte[] b = new byte[1000];
buf = ByteBuffer.wrap(b);
buf.order(ByteOrder.BIG_ENDIAN);
return buf.array();
AND THEN do the same as above, I store a pointer to that byte[] and want to hold on to it for a while. How / when / why is the JVM going to come after that backing byte[] from Java?
void* function()
{
jbyteArray byteArr = (jbytearray)env->CallStaticObjectMethod(testClass, doSomethingMethod);
jbyte *b= env->GetByteArrayElements(byteArr, 0);
return b;
}
Upvotes: 2
Views: 1232
Reputation: 2316
The short answer is: If the function implements a native method, the pointer will be invalid as soon as you return.
To avoid this, you should get a global reference for all objects that you intend to keep valid after returning. See the documentation on local and global references for more information.
To understand better how JNI manages references from native code, see the documentation on PushLocalFrame/PopLocalFrame.
Upvotes: 1