Groovy update that caused a ton of dead GroovyClassLoaders in PermGen

I have a Java 7 project that runs scripts every n minutes by n processes. Here is an example of code that runs scripts.

ScheduledFuture scheduledFuture = scheduledService.scheduleAtFixedRate(new Runnable() { @Override public void run() { try (GroovyClassLoader cl = new GroovyClassLoader()) { // Load up reusable script modules in the class loader Class scriptClass = cl.parseClass(scriptSource); Foo script = optimizationClass.newInstance(); // Tell Groovy that we don't need class meta info GroovySystem.getMetaClassRegistry().removeMetaClass(scriptClass); script.run(); cl.clearCache(); } catch (IOException e) { LOGGER.error("Failed to cleanup Groovy class loader, this will cause a memory leak", e); } } }, 0, scheduledRun, TimeUnit.SECONDS); scheduledFuture.get(); 

For some reason, with Groovy 2.1.7 a memory leak in Perm Gen. When upgrading to Groovy 2.3.8 or Groovy 2.2.0, Perm Gen continues to fill up with the dead class Groovy loaders.

0x000000071ada2cd0 33 488 160 0x000000071b2493c8 dead groovy / lang / GroovyClassLoader $ InnerLoader @ 0x00000007c7b70ef8 0x00000007265883b8 33 488 160 0x0000000725837270 dead groovy / lang / GroovyClassLoader $ InnerLoader @ 0x00000007c7b70ef8 0x00000007157b5da0 26 370736 0x000000072326f468 live org / codehaus / groovy / runtime / callsite / CallSiteClassLoader @ 0x00000007c831d388 0x000000071ada1fb0 32 423 944 0x000000071af03a98 dead groovy / lang / GroovyClassLoader $ InnerLoader @ 0x00000007c7b70ef8 0x0000000719d605b0 32 456 520 0x000000071af04798 dead groovy / lang / GroovyClassLoader $ InnerLoader @ 0x00000007c7b70ef8 0x0000000725b82500 0 0 0x000000072326f468 dead groovy / lang / GroovyClassLoader @ 0x00000007c74c33e8 0x00000007263eef80 34 532 448 0x0000000726d5c678 dead groovy / lang / GroovyClassLoader $ InnerLoader @ 0x00000007c7b70ef8 0x000000072687b3c8 33 485288 0x0000000726c36340 dead groovy / lang / GroovyClassLoader $ InnerLoader @ 0x00000007c7b70ef8 0x0000000725d56db0 33 485288 0x000000072607bcc0 dead groovy / lang / Gr oovyClassLoader $ InnerLoader @ 0x00000007c7b70ef8

I wait until Full GC appears, but it seems that any version after Groovy 2.2 makes Perm Gen fill. I checked the release notes between the version I was on before the updated version, and I did not notice any changes that could cause this.

I checked here for similar questions and tried a few suggestions, but no luck. Any ideas on the reason?

Update:
I made Diff on GrepCode on GroovyClassLoader from 2.1.7 to 2.2.0, and there were no changes. I also took the heap dump file when the application was launched, and there were no paths to the GC roots for strong links.

The problem seems to be here:

 Class scriptClass = cl.parseClass(scriptSource); Foo script = scriptClass.newInstance(); 

When I do not compile the script, I got 0 Groovy ClassLoaders in Perm Gen. When I compile a script but don't run it, I lose Groovy ClassLoaders.

Update:
Found the code causing the leak.

 Foo script = scriptClass.newInstance(); 

I don't know how to fix this, since I need to create a new instance to run the script.

+2
java permgen groovy
source share
2 answers

I had the same problem when using groovy script to compile and work. I finally worked as follows: 1. If you are working with java version prior to 7, you can use the codes below to clear your class after compiling

  public static void clearAllClassInfo(Class<?> type) throws Exception { Field globalClassValue = ClassInfo.class.getDeclaredField("globalClassValue"); globalClassValue.setAccessible(true); GroovyClassValue classValueBean = (GroovyClassValue) globalClassValue.get(null); classValueBean.remove(type); } 

2. otherwise you are lucky because you just need to add properties to SystemProperties

 -Dgroovy.use.classvalue=true 
+4
source share

We had similar problems with a file parser written in groovy, a memory leak like seave - when you do a lot of string manipulation. We also tried clearCache () for the class loader, as well as .removeMetaClass () without using.

We finally circumvented this issue by compiling the groovy module as a jar file and including it in the project.

0
source share

All Articles