JuliaInterop / JavaCall.jl

Call Java from Julia
http://juliainterop.github.io/JavaCall.jl
Other
118 stars 53 forks source link

Create JavaRef, JavaLocalRef, and JavaGlobalRef to hold references and manage memory #124

Closed mkitti closed 4 years ago

mkitti commented 4 years ago

Background: Local and Global Java References

Currently all Java references to objects in JavaCall are "local" Java references for variables that are only meant to live the lifetime of a Java method call after which the Java garbage collector may free the underlying memory. Because the use of these references in JavaCall is occurring outside of the context of a Java method call, currently the local references are never marked for garbage collection. The local part of a Java method call can emulated by the use of JNI.PopLocalFrame and JNI.PushLocalFrame.

However, there are some are some references that we would not like to mark for collection, notably the metaclasses. The JNI also has the concept of global references that are meant to survive a Java method call.

JavaRef, JavaLocalRef, JavaGlobalRef, and JavaNullRef types

To improve memory management, I create a new family of types, JavaRef with JavaLocalRef and JavaGlobalRef subtypes to track the scope of the underlying references. This also helps us to provide the correct deletion procedure for the references. Additionally, I create a JavaNullRef type and a constant J_NULL to track null or deleted references.

JProxy

This also permits advancement of #91 and #112 . JProxy makes some alterations to core JavaCall.jl to introduce global references. This is an alternative design that allows for both local and global references. We will thus backout the changes in to core JavaCall in #112 and use this Java reference management design instead.

Technical Notes

To facilitate easy extraction of the Ptr{Nothing} to pass to the JNI via ccall I overloaded Ptr to replace the reference to the .ptr field of JavaObject.

Pending

For many JNI calls, it would be nice to simply pass the JavaObject rather than having to call Ptr. To allow this, I plan on creating an abstract type in the JNI module. Concrete derivatives of that abstract type then should implement the Base.convert or Base.cconvert methods to convert the concrete type to Ptr{Nothing}. This would allow us to maintain the independence of the JNI module while allowing for alternate implementations.

aviks commented 4 years ago

Conceptually, this looks good. I'd like it if we could run tests for Spark.jl and Taro.jl on this branch, since those two package exercise the JVM much more than JavaCall tests can.

mkitti commented 4 years ago

I just checked Taro.jl. The tests run well against this branch. The one issue is that I had to add write permissions to df-test.xlsx

mkitti commented 4 years ago

I cannot get Spark.jl to work on Linux with Julia 1.3.1 to Julia 1.5-beta1 on Linux. I created an issue here: https://github.com/dfdx/Spark.jl/issues/78