Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JNI object references obtained through the Invocation API: local or global?

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?

like image 712
Flavio Avatar asked Oct 11 '10 14:10

Flavio


People also ask

What are local and global references in JNI?

The JNI divides object references used by the native code into two categories: local and global references. Local references are valid for the duration of a native method call, and are automatically freed after the native method returns. Global references remain valid until they are explicitly freed.

What is JNI global references?

A JNI global reference is a reference from "native" code to a Java object managed by the Java garbage collector. Its purpose is to prevent collection of an object that is still in use by native code, but doesn't appear to have any live references in the Java code. A JFrame is a java. awt.

What is JNI and how it works?

JNI is the Java Native Interface. It defines a way for the bytecode that Android compiles from managed code (written in the Java or Kotlin programming languages) to interact with native code (written in C/C++).

Does JNI use reflection?

Each method that can be called via JNI has a reflection metadata object. The address of this object is used as the method's jmethodID .


2 Answers

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.

like image 161
cmccabe Avatar answered Sep 19 '22 01:09

cmccabe


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().

like image 41
Xeor Avatar answered Sep 20 '22 01:09

Xeor