Seva Alekseyev Seva Alekseyev - 1 month ago 8
Java Question

JNI local ref lifetime in a JVM host app

The JNI docs state that local Java object references are in scope until the native method returns; also that they're local to the thread.

When an application hosts a Java VM, Java object references might be created outside of any native method. Once a JVM is running, the host app may obtain a

JNIEnv
and create Java objects all it wants. One assumes this scenario produces local refs.

What's the lifetime of those, please? Do they live as long as the JVM lives (unless freed explicitly)? Are they thread local too? If on a worker thread, do they go out of scope once the thread is detached from a JVM?

Specifically about thread locality: so far, reusing class objects (as returned from
FindClass()
) between threads would work as expected for me. But is that a violation of JNI rules?

Answer

A valid JNIEnv that can be used to create local references may be obtained through:

  1. A native method call. Local references will be valid until the method returns.
  2. JVMTI callback. Similarly, local references will live until the callback returns.
  3. GetEnv call.

    3.1. From JNI_OnLoad, Agent_OnLoad, Agent_OnAttach entries. Local references created inside these entries are valid until the return from the entry.

    3.2. From a thread attached by AttachCurrentThread function. References will be alive until DetachCurrentThread is called.

All local references are only valid in the thread in which they are created. The native code must not pass local references from one thread to another.

Note that JVM guarantees1,2 that 16 local references can be created in one frame. If you need more local refs, you have to manage them explicitly with PushLocalFrame / PopLocalFrame JNI functions.

jclass, jthread, jstring, jarray etc. are all JNI references like jobject. They also need to be managed, unlike jmethodID and jfieldID which are not JNI references.

Comments