JNI 参考说
“本地引用在本地方法调用期间有效。本地方法返回后它们会自动释放。
资料来源:http ://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html#global_local
我有点迷失在这里。根据上述,我必须显式调用NewGlobalRef并将调用返回的对象传递给NewObject。我试过了,似乎当 GC 启动时,它不会收集我的引用(就像某些东西仍然保留在它们上一样)。考虑以下项目: Main.java:
package lv.example;
import java.io.IOException;
import java.util.ArrayList;
class Main {
public static void main(String[] args) {
ArrayList<Object> store = new ArrayList<Object>();
while(true) {
Object d = null;
try {
int c = System.in.read();
d = Dummy.getWeakGlobalRef();
if(c == 'c')
store.clear();
store.add(d);
System.out.println(d);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
虚拟.java:
package lv.example;
class Dummy {
static {
System.loadLibrary("dummy");
}
native static Dummy getLocalRef();
native static Dummy getGlobalRef();
native static Dummy getWeakGlobalRef();
@Override
protected void finalize() throws Throwable {
System.out.println("Finalized");
}
}
libdummy.so 包含本机方法的实现:
JNIEXPORT jobject JNICALL Java_lv_example_Dummy_getLocalRef (JNIEnv *env, jclass cls) {
jmethodID id = env->GetMethodID(cls, "<init>", "()V");
return env->NewObject(cls, id);
}
JNIEXPORT jobject JNICALL Java_lv_example_Dummy_getGlobalRef (JNIEnv *env, jclass cls) {
jmethodID id = env->GetMethodID(cls, "<init>", "()V");
return env->NewGlobalRef(env->NewObject(cls, id));
}
JNIEXPORT jobject JNICALL Java_lv_example_Dummy_getWeakGlobalRef (JNIEnv *env, jclass cls) {
jmethodID id = env->GetMethodID(cls, "<init>", "()V");
return env->NewWeakGlobalRef(env->NewObject(cls, id));
}
主循环表现出的行为对我来说似乎很奇怪:1)当我调用getWeakGlobalRef或getLocalRef并清除ArrayList时,GC 似乎收集了我创建的所有Dummy对象。2)当我调用getGlobalRef时,无论我是否清除ArrayList ,都不会收集任何对象。l
我在这里有点困惑,这是否意味着我可以将本地方法的本地引用返回给 Java 代码?