我不知道,你要實現,但這裏是什麼它是如何工作的basicly:
我是否可以使用hold_ref後來在本地層參考釋放MyObj中?
是的,你可以和應該使用env->DeleteGlobalRef(myObj)
來釋放您所創建的全球參考,因此垃圾收集器清理和finaly銷燬對象。
然後Java層中的myObj爲null?如果不是,我如何通過本機代碼釋放此對象?
當您從jni本機代碼中刪除引用時,您的Java變量將無法變爲空。 Java本身擁有一個引用來防止垃圾回收對象被刪除。
您可能需要使用這種方式:
C++
jobject* hold_ref;
JNIEXPORT jobject JNICALL nativeCreateObject(JNIEnv *env ...) {
.....
result = env->NewGlobalRef(jobj);
hold_ref = &result;
return result;
}
JNIEXPORT void JNICALL nativeDestroyObject(JNIEnv *env ...) {
.....
env->DeleteGlobalRef(jobj);
hold_ref = nullptr;
}
JAVA
// Creates two references (native and local variable)
Object myObj = nativeCreateObject();
// Deletes the native reference, but not the local one
nativeDeleteObject(myObj);
// myObj != null
myObj = null;
// now there is no reference to your created object
// the garbage collector may destroy it any time
如果你想以某種方式無效的對象,我建議來管理國家和拋一個例外,如果對象是這樣失效的:
class MyInvalidateableObject {
private boolean invalidated = false;
public void invalidate() {
this.invalidated = true;
}
public void foo() {
if (invalidated)
throw new IllegalStateException("Object has been invalidated");
... // do the normal stuff
}
}
只需從本機代碼調用invalidate()
即可防止它再次被使用。
不需要。您需要閱讀[JNI規範的第4章](https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#global_and_local_references)。 – EJP
@EJP感謝您的信息。閱讀後...我仍然沒有找到答案。你能幫我簡單地給我一些關於這個問題的建議嗎?提前致謝! – ignorer
'result'和'myObj'是對同一個對象的兩個不同的引用。只要至少有一個引用存在,該對象就不能被垃圾回收。 _Maybe_你可以將'nativeCreateObject'的結果包裝在Java的'WeakReference'中(這不是我曾經試過的,所以我沒有做任何保證)。順便說一句,'* hold_ref = NULL;'不是你如何刪除一個全局引用。 – Michael