5

I'm using the JNI invocation API, which starts a JVM within a C program; in this situation, you get a JNIEnv pointer which remains valid until you explicitly destroy the JVM. Does the local/global distinction still apply here? What's the meaning of a local reference to a newly created object, since the JNIEnv remains in scope all the time?

Flavio
  • 11,925
  • 3
  • 32
  • 36

3 Answers3

7

The JNI book is a little terse about this situation, but you can figure it out if you study it long enough. Basically, when you attach a native C thread to the JVM, you create a local context which can store some local references.

These local references will never be freed until you manually free them with DeleteLocalRef, or you destroy the local context by calling DetachThread. Since you're probably not doing a lot of attaching and detaching to JVMs, it's very important for you to call DeleteLocalRef on every local reference you create.

The natural next question is "why create global refs at all, if local refs don't get GC'ed until the JVM is detached?" Well, local references cannot be shared between threads. So you still have to create global references to do that.

cmccabe
  • 4,160
  • 1
  • 24
  • 10
  • Now that I have more JNI experience, I agree this is is the clearest answer. – Flavio Jun 04 '13 at 08:35
  • 1
    The comment about local refs never being freed brings up a subtlety of using JNI: if you do convert a local ref into a global ref, make sure you delete the local ref afterwards. Otherwise the local ref will not be deleted, and you will have a memory leak. – Trebor Rude Jul 09 '13 at 23:09
1

I think the thread which created JVM becomes Java thread, which, like any thread created in Java, or attached via AttachCurrentThread(), has its local stack frame. So any object you create, becomes a local reference in this stack frame, which will expire when you destroy JVM (you can't detach main thread), or call DeleteLocalRef().

Xeor
  • 1,846
  • 1
  • 12
  • 12
  • Do you have any documentation reference on this? And is it legal to pass such local references to other JNIEnv obtained when Java makes a native C call? – Flavio Oct 14 '10 at 13:15
1

Presumably a call DettachCurrentThread() releases the references as well. Unfortunately the JNI spec does not clearly define the behavior of references for the invocation API, and it may be that the actual semantics may depend on the specific JVM implementation :S

JCL
  • 11
  • 1