JNI文档声明本地Java对象引用在本机方法返回之前都在作用域中;而且它们对于线程来说是本地的。
当应用程序承载Java VM时,可以在任何本机方法之外创建Java对象引用。一旦JVM开始运行,宿主应用程序就可以获得一个JNIEnv
并创建它想要的所有Java对象。假设此场景产生本地引用。
请问这些的寿命是多少?它们是否与JVM的寿命一样长(除非显式释放)?它们也是线程本地的吗?如果在工作线程上,一旦线程与JVM分离,它们会超出作用域吗?
特别关于线程局部性:到目前为止,在线程之间重用类对象(从FindClass()
返回)对我来说是预期的。但这违反了JNI规则吗?
一个可以用来创建本地引用的有效的JNIEnv
可以通过以下方式获得:
- 本机方法调用。在方法返回之前,本地引用将一直有效。
- JVMTI回调。类似地,局部引用将一直存在,直到回调函数返回。
-
GetEnv电话。
3.1。从
JNI_OnLoad
,Agent_OnLoad
,Agent_OnAttach
条目。在这些条目中创建的本地引用在条目返回之前都是有效的。3.2。从AttachCurrentThread函数附加的线程。在DetachCurrentThread被调用之前,引用都是活的
所有的本地引用只在创建它们的线程中有效。本机代码不能将本地引用从一个线程传递到另一个线程。
注意JVM保证1,2可以在一个帧中创建16个本地引用。如果你需要更多的本地参考,你必须使用PushLocalFrame/PopLocalFrame JNI函数显式地管理它们。
jclass
, jthread
, jstring
, jarray
等都是JNI引用,如jobject
。它们也需要被管理,不像jmethodID
和jfieldID
不是JNI引用。