5

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

4

3 回答 3

6

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

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

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

于 2012-07-02T17:02:45.220 回答
1

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

于 2011-08-09T17:58:02.343 回答
1

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

于 2010-10-12T20:38:04.047 回答