Returning local reference created by JNI from a native method

大憨熊 提交于 2019-11-29 12:45:37

The JVM needs to know whether the native code is keeping its own references to the objects. That is if the object were deleted, is it possible for the C/C++ code to still try access it (probably causing a segfault). The objects with global references are not garbage collected because the native code has indicated that it might still need them. The objects with local references can be garbage collected because the function where the references were created has already returned to java. The objects with weak global references can be garbage collected because the native code has indicated it will use IsSameObject to check if the object with the weak reference has been garbage collected so that it will behave correctly using the object only if it has not been garbage collected.

re:

So this means, that New*Ref is for pinning for native code only? Does JVM track a "local reference" to the point where I assign it to a instance of Java variable?

Local references are tracked until the return to java. Assigning it to a java variable doesn't remove the reference although it would independently prevent garbage collection of that object. The returned value would have a reference on the stack preventing garbage collection until it could be assigned to a java variable so there is no need for a returned object to have a global reference unless the native code might access that same object after the return. Without the local reference the JVM might garbage collect the object while the JNI function were executing since the garbage collector runs in another thread. Normally one doesn't need to explicitly call NewRef/DeleteRef as

All Java objects passed to the native method (including those that are returned as the results of JNI function calls) are automatically added to the registry(ie given a local reference).

(quoted from https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#implementing_local_references)

Cases you might need to do it.

The native function spawns a thread that continues using the object after control is returned to java in the original thread.

The native function stores a copy of the reference in some global variable for use in subsequent calls from java.

You want to explicitly delete references while the function is running to conserve memory during a function that might take a while.

Yes. A JNI local reference refers to an object; You can return a reference to that object. Back on the Java side, "local reference" doesn't have any meaning.

The garbage collector works by starting with a set of root "live" references and marking any object reachable from them as "live". Every other object is subject to deletion.

JNI's local and global references are kept in the set of root references. Local references are automatically removed when the native method that created them returns. You can, and sometimes should, delete local references before that. Global references are explicitly created and removed by native code at any time.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!