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