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();
}
}
}
}
Dummy.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 は作成したすべてのダミーオブジェクトを収集するようです。2) getGlobalRef を呼び出すと、ArrayListをクリアするかどうかに関係なく、オブジェクトは収集されません。l
ここで少し混乱しています。それは、ローカル参照をネイティブ メソッドから Java コードに戻すことができるということですか?