简体   繁体   中英

Groovy: re-compile a class from file and memory leaks

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?

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)}"
}

在此处输入图片说明

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).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM