【问题标题】:Simple Grails 2.5.1 application leaks classloaders with Groovy 2.4.4简单 Grails 2.5.1 应用程序使用 Groovy 2.4.4 泄漏类加载器
【发布时间】:2016-02-23 10:15:00
【问题描述】:

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

我的设置如下:

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

Tomcat也是全新安装,只修改了两处(因为我想在生产中使用):

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

context.xml
&lt;Context antiResourceLocking="true"&gt;

我已经重新启动了 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,所以我真的很困惑这些实例如何没有被垃圾收集。

有没有人遇到过类似的问题?什么可能导致此加载程序挂起?

【问题讨论】:

  • 你可以手动部署你的类而不是战争

标签: grails groovy memory-leaks classloader redeploy


【解决方案1】:

此问题与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'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-24
    • 1970-01-01
    • 2014-04-12
    • 2013-03-15
    • 2014-05-14
    • 2011-02-24
    • 2010-10-17
    相关资源
    最近更新 更多