Groovy: перекомпилируйте класс из файлов и утечек памяти

Согласно справочному документу:

GroovyClassLoader хранит ссылки на все классы, которые он создал, поэтому легко создать утечку памяти. В частности, если вы выполняете один и тот же сценарий дважды, если это строка, вы получаете два разных класса!

Я использую файл в качестве источника для разбора, но отключил кеширование:

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

вывод журнала всегда

класс MyClass <=> класс MyClass равен: ложь

Если я прокомментирую строку src.cachable = false, тогда экземпляры класса становятся равными, но они НЕ перекомпилируются, даже если базовый файл изменился.

Отсюда вопрос: как правильно перекомпилировать классы без утечки памяти?

2 ответа

Решение

Проведя некоторые эксперименты, я понял, что переключаюсь обратно на использование String:

String src = 'class A {}'
Class clazz = groovyClassLoader.parseClass src
log.info groovyClassLoader.loadedClasses.join( ', ' )

загруженные классы не меняются по длине, даже если у класса есть некоторые замыкания внутри (которые также отображаются как классы).

Я сделал следующий тест и не вижу утечки памяти.

как по мне нормальная работа GC.

ссылка на ваш класс будет жива, пока жив любой экземпляр класса.

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

Другие вопросы по тегам