We unfortunately got PermgenError. jmap -permstat return something like this:
0x00000006c17f8520 1 1968 0x00000006ad000000 dead sun/reflect/DelegatingClassLoader@0x00000007e00686e0
0x00000006babab308 3 19920 0x00000006b6874f88 dead groovy/lang/GroovyClassLoader$InnerLoader@0x00000007e975bb80
0x00000006bca26800 3 15776 0x00000006b6874f88 dead groovy/lang/GroovyClassLoader$InnerLoader@0x00000007e975bb80
0x00000006bb84db80 3 16176 0x00000006b6874f88 dead groovy/lang/GroovyClassLoader$InnerLoader@0x00000007e975bb80
0x00000006b71dffd0 3 19272 0x00000006b6874f88 dead groovy/lang/GroovyClassLoader$InnerLoader@0x00000007e975bb80
after 2 hours jmap -permstat return:
0x00000006c17f8520 1 1968 0x00000006ad000000 dead sun/reflect/DelegatingClassLoader@0x00000007e00686e0
0x00000006babab308 3 19920 0x00000006b6874f88 dead groovy/lang/GroovyClassLoader$InnerLoader@0x00000007e975bb80
0x00000006bca26800 43 437232 0x00000006b6874f88 dead groovy/lang/GroovyClassLoader$InnerLoader@0x00000007e975bb80
0x00000006bb84db80 3 16176 0x00000006b6874f88 dead groovy/lang/GroovyClassLoader$InnerLoader@0x00000007e975bb80
0x00000006b71dffd0 7 16176 0x00000006b6874f88 dead groovy/lang/GroovyClassLoader$InnerLoader@0x00000007e975bb80
As you can see the number of class loaded by classLoader incresed for example from 3 to 43. This is only short fragment of permstat - (total = 4676 53521 436264528 alive=1, dead=4675). We run java with parameters:
-XX:+DisableExplicitGC -server -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:MaxGCPauseMillis=800 -XX:+CMSParallelRemarkEnabled -XX:CMSFullGCsBeforeCompaction=1 -XX:+CMSClassUnloadingEnabled
but in permstat all clasloaders are dead. Our code which parse groovy classes:
class GroovyInvoker {
private static GroovyClassLoader gcl = new GroovyClassLoader(Thread.currentThread()
.getContextClassLoader());
protected static GroovyInvoker getInstance(String fileName, String className)
throws BaseScriptingException {
GroovyInvoker instance = new GroovyInvoker();
instance.setFileName(fileName);
instance.setClassName(className);
Class clazz;
clazz = GroovyInvoker.gcl.parseClass(instance.getFile(fileName));
Script aScript = (Script) clazz.newInstance();
instance.setScript(aScript);
return instance;
}
}
I read this topic: Locating code that is filling PermGen with dead Groovy code and answer with metaClassRegistry problem but we can't test it now on prod server. My questions is: why number of classes loaded by GroovyClassLoader is increasing when Groovy is using cache? Shouldn't this number be constant? why gc is not collecting dead classLoaders?
Java version 1.6.0_26. Groovy version 1.5.8.