【问题标题】:GroovyClassLoader and permgenGroovyClassLoader 和 permgen
【发布时间】:2013-12-13 12:33:33
【问题描述】:

不幸的是,我们遇到了 PermgenError。 jmap -permstat 返回如下内容:

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

2 小时后 jmap -permstat 返回:

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

如您所见,classLoader 加载的类数量从 3 增加到 43。 这只是 permstat 的一小部分 - (总数 = 4676 53521 436264528 存活 = 1,死亡 = 4675)。我们用参数运行java:

-XX:+DisableExplicitGC -server -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:MaxGCPauseMillis=800 -XX:+CMSParallelRemarkEnabled -XX:CMSFullGCsBeforeCompaction=1 -XX:+CMSClassUnloadingEnabled

但是在 permstat 中所有的类加载器都死了。 我们解析 groovy 类的代码:

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

我阅读了这个主题:Locating code that is filling PermGen with dead Groovy code 并回答了 metaClassRegistry 问题,但我们现在无法在 prod 服务器上对其进行测试。我的问题是: 为什么当 Groovy 使用缓存时,GroovyClassLoader 加载的类数量会增加?这个数字不应该是恒定的吗? 为什么 gc 不收集死类加载器?

Java 版本 1.6.0_26。 Groovy 版本 1.5.8。

【问题讨论】:

  • 哪个版本的 Groovy?
  • groovy 版本:1.5.6

标签: java groovy


【解决方案1】:

我认为它与此有关: http://jira.codehaus.org/browse/GROOVY-6494

如果你不需要上下文类加载器,那么 GroovyClassLoader 就不会泄漏。

【讨论】:

    猜你喜欢
    • 2014-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-20
    • 2012-02-24
    • 1970-01-01
    • 2014-06-21
    • 1970-01-01
    相关资源
    最近更新 更多