1. I’m having a bit of trouble parsing this paragraph:
> The reason eval loads a new classloader every time is justified as dynamically generated classes cannot be garbage collected as long as the classloader is referencing to them. In this case, single classloader evaluating all the forms and generating new classes can lead to the generated class not being garbage collected.
To avoid this, a new classloader is being created every time, this way once the evaluation is done. The classloader will no longer be reachable and all it’s dynamically loaded class.
It sounds like the solution they adopted was to instantiate a brand new classloader each time a dynamic class is evaluated, rather than use a singleton classloader for the app’s lifetime.
Dynamic classes cannot be GC'd without the classloader being dereferenced. In this case, if eval used an existing classloader we would end up exhausting metaspace and leading to MaxPermGen exception.
Initial Clojure implementation was checking for an already created classloader and tried to reuse. They had commented out the code that was doing it.
These days there is some
Machinery in the JVM for creating truly anonymous classes that can be garbage collected (https://docs.oracle.com/en/java/javase/22/docs/api/java.base......) ), but they are trickier to generate as they can’t have static fields (you don’t have a class name so have no way to refer to them) etc.
Side note: You’re using the term “dereference” incorrectly (also in the article). It doesn’t mean “drop references”. It means “going from the reference to the thing being referenced”, or (in other words) “accessing the thing that is being referenced” [0]. It doesn’t mean the reference is going away.
> It sounds like the solution they adopted was to instantiate a brand new classloader each time a dynamic class is evaluated ...
I was confused too (and I may still be) but that's now how I understood their solution.
Their solution, IIUC from reading TFA, is that they simply didn't use eval at all anymore. So the whole "eval loads a new classloader" thinggy (so that it can be GC'ed later on) is totally moot.
1. I’m having a bit of trouble parsing this paragraph:
> The reason eval loads a new classloader every time is justified as dynamically generated classes cannot be garbage collected as long as the classloader is referencing to them. In this case, single classloader evaluating all the forms and generating new classes can lead to the generated class not being garbage collected.
To avoid this, a new classloader is being created every time, this way once the evaluation is done. The classloader will no longer be reachable and all it’s dynamically loaded class.
It sounds like the solution they adopted was to instantiate a brand new classloader each time a dynamic class is evaluated, rather than use a singleton classloader for the app’s lifetime.