Simple Grails 2.5.1应用程序使用Groovy 2.4.4泄漏类加载器

时间:2015-11-20 19:47:41

标签: grails groovy memory-leaks classloader redeploy

我在Tomcat 8中热重新部署一个简单的Grails应用程序时出现问题。

我的设置如下:

  • Grails 2.5.1使用create-app
  • 创建的全新应用程序
  • Tomcat 8.0.28(64位Linux二进制版本)
  • Java 1.8.0_65-b17 HotSpot服务器VM

Tomcat也是一个全新的安装,只修改了两件事(因为我想在生产中使用它们):

的server.xml
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" undeployOldVersions="true">

的context.xml
<Context antiResourceLocking="true">

我重新启动了Tomcat服务器。根据JVisualVM,它加载了2398个类。复制grails prod war生成的war文件并等待部署完成后,它加载了10 022个类。在再次复制战争,从而触发重新部署后,它有16 300个类。

我在第一次部署之后进行了堆转储,第二次,并使用eclipse MAT分析了类加载器,我可以看到有一个额外的org.apache.catalina.loader.WebappClassLoader有6 138个加载的类(所以有两个在总)。

堆空间保持相当稳定,只有MetaSpace使用量显着增加(与类的数量大致相同)。

更新

使用MAT深入挖掘,我注意到总有9个实例使类加载器保持活动状态。它们是org.codehaus.groovy.reflection.ClassInfo的实例(每个原始java类型包装器和Void一个)。这些ClassInfos仅由java.lang.ClassValue$Entry引用,它扩展了WeakReference,所以我真的很困惑这些实例是如何收集垃圾的。

有没有人有类似的问题?什么可能导致这个装载机徘徊?

1 个答案:

答案 0 :(得分:0)

此问题与https://issues.apache.org/jira/browse/GROOVY-7591

有关

我不完全理解这个问题,但我会尽快描述一下:
使用ClassValue(由于JDK错误)可防止对象被垃圾回收。 Groovy 2.4.5中的提交暂时禁用ClassValue,同时修复了JDK错误。

Grails 2.5.1默认使用groovy 2.4.4,所以为了解决这个问题,我在BuildConfig.groovy中替换了它,并重建了应用程序。

build 'org.codehaus.groovy:groovy-all:2.4.5'
compile 'org.codehaus.groovy:groovy-all:2.4.5'