通过Invocation API获得的JNI对象引用:本地还是全局?

时间:2010-10-11 14:35:24

标签: reference java-native-interface invocation

我正在使用JNI调用API,它在C程序中启动JVM;在这种情况下,您将获得一个JNIEnv指针,该指针在您明确销毁JVM之前一直有效。 本地/全球的区别是否仍然适用于此?对新创建的对象的本地引用的含义是什么,因为JNIEnv一直在范围内?

3 个答案:

答案 0 :(得分:6)

JNI书对这种情况略显简洁,但如果你研究的时间足够长,你可以弄明白。基本上,当您将本机C线程附加到JVM时,您可以创建一个可以存储一些本地引用的本地上下文。

在您使用DeleteLocalRef手动释放它们之前,永远不会永远,或者通过调用DetachThread来破坏本地​​上下文。由于您可能没有对JVM进行大量附加和分离,因此在您创建的每个本地引用上调用DeleteLocalRef非常重要。

自然的下一个问题是“为什么创建全局引用,如果本地引用在JVM分离之前没有得到GC?”好吧,线程之间不能共享本地引用。所以你仍然需要创建全局引用来做到这一点。

答案 1 :(得分:1)

我认为创建JVM的线程变成了Java线程,它与在Java中创建或通过AttachCurrentThread()连接的任何线程一样,具有其本地堆栈帧。因此,您创建的任何对象都将成为此堆栈帧中的本地引用,当您销毁JVM(无法分离主线程)或调用DeleteLocalRef()时,它将过期。

答案 2 :(得分:1)

大概是调用DettachCurrentThread()也会释放引用。 不幸的是,JNI规范没有明确定义调用API的引用行为,可能实际的语义可能依赖于特定的JVM实现:S