tweag/inline-java

jni: Delete global reference in bound threads

facundominguez opened this issue · 2 comments

The current approach is to have the Haskell GC delete the global references. Unfortunately, the GC deletes global references using unbound threads which are unsafe to use when making JNI calls.

The simplest fix of all is to wrap finalizers with Foreign.JNI.runInAttachedThread.

If the above is too slow, another solution is to implement a pool of threads to make sure finalizers are expediently executed once the GC makes up its mind to run them.

Lastly, #73 might also offer a solution to this problem.

If the above is too slow, another solution is to implement a pool of threads to make sure finalizers are expediently executed once the GC makes up its mind to run them.

Using a threadpool is probably over-complicating the solution. A single bound thread could do if performance is not a concern.

If the java heap is full and needs fast deletion of global references, can java force the Haskell GC to run the finalizers promptly before java finishes garbage collection? If not, which scenario would take advantage of a fast deletion of local references?

Next steps:

  • Change the finalizers calling deleteGlobalRefNonFinalized to use runInAttachedThread.
  • Measure how long it takes attaching and detaching a thread to the JVM when compared with the time it takes to delete deleteGlobalRefNonFinalized.
  • Have the finalizers execute deleteGlobalRefNonFinalized on a dedicated attached thread and measure how long it takes to delete a bunch of global references.