public class GroovyClassInfoHandler
extends Object
This class handles the cleanup of groovy classes in the system class loader
Recurrent executions of groovy scripts provokes a memory leak if groovy generated classes are not cleaned from the system class loader
The difficulty is that, on a ProActive Node, multiple executions of groovy scripts can happen in parallel from multiple sources (selection scripts, clean script, fork env scripts, non-forked tasks)
Additionally, only a System.gc() ensure proper removal of groovy classes from the JVM. If System.gc() is not called,
the same classes will be detected again and marked again for cleanup. When a lot of groovy scripts are run, this can dramatically decrease
performances as 100K+ groovy classes may be detected over and over. Furthermore, while the long cleanup is performed, it will block any groovy script execution (due to some internal lock mechanism in groovy).
Accordingly, the cleaning mechanism must:
1) Take a snapshot of groovy generated classes when no script is currently running. Also, take a snapshot of entries created by groovy in the system class loader private field parallelLockMap (this is achieved via reflection).
2) In a dedicated background thread, perform cleanup of these classes and lock keys periodically and call System.gc() immediately.
To achieve this, the classes use locks and atomic objects to synchronize and share objects with the background cleanup.
The background cleanup is scheduled via a java-property configurable period in seconds (defaults to 10 seconds).
Caveats :
- the cleanup only triggers when no script is running (a script running eternally on the node will prevent any cleanup from occurring)
- the call to System.gc() is mandatory after each cleanup, but a call to System.gc() is not without implications.
Calling it on a ProActive Node frequently will not have a sensible impact, but calling it frequently on the server may decrease its performance.
Accordingly, the clean period must be set differently on the server than the nodes.