Can Java object be JNI released?
I am creating a Java object by calling native code that returns a job value.
Java code:
Object myObj = nativeCreateObject();
Source:
jobject* hold_ref;
JNIEXPORT jobject JNICALL
nativeCreateObject(JNIEnv *env ...) {
.....
result = env->NewGlobalRef(jobj);
hold_ref = &result;
return result;
}
My question is, can I use hold_ref later to free myObj by reference in its own layer? for example native code:
*hold_ref = NULL;
Then myObj in Java layer is null? if not, how can I free this object with my own code?
source to share
I'm not sure what you want to achieve, but this is how it works:
can i use hold_ref later to free myObj by reference in its own layer?
Yes, you can and should use env->DeleteGlobalRef(myObj)
to free the global reference you created so that the garbage collector can clean up and permanently destroy the object.
Then myObj in Java layer is null? if not, how can I free this object with my own code?
It is not possible for your Java variable to go back to zero magic when removing a reference from jni's native code. Java itself contains a link to prevent garbage collection of an object.
You can use it like this:
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
If you want to invalidate your object somehow, I suggest managing the state and throwing an exception if the object was invalid like this:
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
}
}
Just call invalidate()
your object from your own code so that it is no longer used.
source to share