Must I DeleteLocalRef an object I have called NewGlobalRef on?

1.9k Views Asked by At

As we know, creating Java objects in a thread owned by C/C++ we are responsible to call DeleteLocalRef or Push/Pop LocalFrame as needed.

I have some code like

jbyteArray buffer = env->NewByteArray((jsize)requiredSize);
longTermBufferReference = (jbyteArray)env->NewGlobalRef(buffer);

where native code creates a byte array, which it re-uses across multiple threads/calls, once we are done with it, I call DeleteGlobalRef on the buffer.

The question is, must I call DeleteLocalRef on buffer when I'm done, or does the GlobalRef take complete ownership of the object?

3

There are 3 best solutions below

1
On BEST ANSWER

In a garbage collected system, there is no such thing as object ownership. There are root object references and object references that are reachable directly or indirectly from the roots. (Weak references are not considered).

Both JNI local references and JNI global references are root references. Creating additional references does not affect existing references nor remove them from the list of root references.

So, yes, the local reference must be deleted (just as the global reference must be deleted). You already know that you can do it explicitly with DeleteLocalRef or PopLocalFrame, or, when a JNI native method returns, JNI effectively calls PopLocalFrame automatically.

2
On

The question is, must I call DeleteLocalRef on buffer when I'm done

No, you can leave it to be deleted automatically when your JNI method returns, or by PopLocalFrame() if you use that. But local references are a scarce resource: if your JNI function uses a lot of them you should release them ASAP.

0
On

To add to what @EJP has said: an object becomes eligible for garbage collection only when there are no (strong) references to it anymore. When you do NewGlobalRef you create a second reference to your object increasing the number of references to 2. The local reference will still be there.

It will be deleted by the runtime when your function exits, but suppose your function was a long one. If you called DeleteGlobalRef, you would delete the global reference, but the local reference would still be unaffected. Number of references: 1. Only after deleting this one too would the garbage collector be able to claim that object.