JNIEnv::take_rust_field
seems meant for use with java.lang.Object.finalize
, but that is deprecated
#535
Labels
JNIEnv::take_rust_field
seems meant for use with java.lang.Object.finalize
, but that is deprecated
#535
When using
JNIEnv::set_rust_field
, there does not appear to be any non-deprecated way to guarantee that the native memory will eventually be deallocated.In the old days, the standard way to free native memory resources was to override the
java.lang.Object.finalize()
method. In this case,finalize
could be a native method that callsJNIEnv::take_rust_field
.This still works, more or less, but
finalize
has issues and has been deprecated since Java 9. The current best practice is to use ajava.lang.ref.Cleaner
. When using that, though, there is no way to read the fields of the original object, and therefore no way to useJNIEnv::take_rust_field
. By the time the cleanup function is called, the original object is already gone.So, to use
Cleaner
to free Rust memory, one would need to do something like this:That is, the pointer is stored in two places:
Example.ptr
. Instance methods ofExample
read this field.Cleaner.register
. When the corresponding instance ofExample
is garbage collected, this cleanup function calls the static native methodfree
with the pointer.Besides not using any deprecated Java methods, this also has the advantage that it does not involve any mutex locking. Neither the Java monitor lock nor a Rust mutex is needed to safely read the native memory that
Example.ptr
points to, as long as there is a live reference to theExample
instance that owns it (although writing would still need some sort of synchronization device, just like with RustArc
).But although the Java code is pretty straightforward, the Rust side of this is complicated and delicate. I wonder if there's some way to wrap a nice API around it.
The text was updated successfully, but these errors were encountered: