Reputation: 20699
As per ref-doc:
A GroovyClassLoader keeps a reference of all the classes it created, so it is easy to create a memory leak. In particular, if you execute the same script twice, if it is a String, then you obtain two distinct classes!
I use a file as a source for parsing but turned caching off:
GroovyCodeSource src = new GroovyCodeSource( file )
src.cachable = false
Class clazz = groovyClassLoader.parseClass src
Class clazz1 = groovyClassLoader.parseClass src
log.info "$clazz <=> $clazz1 equal: ${clazz == clazz1}"
the log output is always
class MyClass <=> class MyClass equal: false
If I comment the line src.cachable = false
, then the class instances become equal, but they are NOT re-compiling even though the underlying file has changed.
Hence the question: how can I re-compile classes properly without creating a memory leak?
Upvotes: 2
Views: 392
Reputation: 20699
After doing some experiments, I figured out that switching back to using String:
String src = 'class A {}'
Class clazz = groovyClassLoader.parseClass src
log.info groovyClassLoader.loadedClasses.join( ', ' )
the loaded classes do not change in lenght, even if a class has some Closures inside (which appear as classes as well).
Upvotes: 0
Reputation: 28564
i did the following test and don't see any memory leak.
as for me, the normal GC work.
the link to your class will be alive while any instance of class is alive.
GroovyCodeSource src = new GroovyCodeSource( 'println "hello world"', 'Test', '/' )
src.cachable = false
def cl=this.getClass().getClassLoader()
for(int i=0;i<1000000;i++){
Class clazz = cl.parseClass src
if(i%10000==0)println "$i :: $clazz :: ${System.identityHashCode(clazz)}"
}
Upvotes: 1