grails - 简单Grails 2.5.1应用程序使用Groovy 2.4.4泄漏类加载器

标签 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文件并等待部署完成后,它已加载了10022个类。在再次复制 war 并触发重新部署后,它有16 300个类(class)。

    我在第一手部署后进行了堆转储,然后进行了第二次,并使用eclipse MAT分析了类加载器,我可以看到有一个额外的org.apache.catalina.loader.WebappClassLoader和6138个已加载的类(因此总共有两个)。

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

    更新

    使用MAT进行更深入的研究,我注意到总是有9个实例使类加载器保持 Activity 状态。它们是org.codehaus.groovy.reflection.ClassInfo的实例(每个原始Java类型包装器和Void都一个)。这些ClassInfos仅由java.lang.ClassValue$Entry引用,它扩展了WeakReference,因此我真的很困惑,这些实例如何不被垃圾收集。

    有人遇到过类似的问题吗?是什么原因导致此装载机闲逛?

    最佳答案

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

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

    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'
    

    关于grails - 简单Grails 2.5.1应用程序使用Groovy 2.4.4泄漏类加载器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33834920/

    相关文章:

    spring - 另一个 Controller 中的Grails Spring安全性登录表单

    Jenkins DSL-解析Yaml以进行复杂处理

    groovy - 如何在gsp中使用replaceAll?

    swift - Reactive Cocoa swift 3.0 上的内存泄漏

    javascript - Javascript/垃圾收集器中的循环引用

    java - 何时生成堆转储

    grails - Grails运行命令错误

    grails - MarkupBuilder-如何添加表td属性 “title”

    grails - 如何将 Grails 中选择框的可见大小限制为 1?

    hibernate 异常 : No session currently bound to execution context