Unloading Clojure vars from JVM thread-local space

2019-07-03 11:26发布

问题:

I'm writing a plugin for BaseX in Clojure, built via "lein uberjar" with the Clojure interpreter included. For the most part, this works well.

However -- when running via the BaseX HTTP instance, evaluation takes place inside Jetty's thread pool rather than having threads thrown away after a client disconnects.

As loading the plugin loads Clojure's classes through a custom classloader, and throwing away the (AOT-compiled) object instance which acts as the plugin's entry point does not discard the vars placed by Clojure in thread-local space, a classloader leak results with PermGen space being eventually exhausted by multiple instances of the Clojure interpreter.

How can this be resolved? I can make reasonable non-Clojure-specific changes to BaseX's module load/unload mechanism if necessary.

回答1:

This idea might (or might not) work:

  1. Don't make an uberjar, keep Clojure jars separate;

  2. push Clojure jars up the classloader hierarchy by putting them into the main classpath of BaseX (edit the command line that starts BasexX server, something like java -cp BaseX.jar;clojure.jar org.basex.BaseXServer);

  3. Package your plugin as a jar with just your code in it and rely on the Clojure classes already present in the main classpath.