【问题标题】:Tomcat and JAXB memory leaksTomcat 和 JAXB 内存泄漏
【发布时间】:2013-09-21 23:45:39
【问题描述】:

我已经追了几天了。 我们在我们的应用程序中使用 JAXB,即 sun 实现。停止 Tomcat(6 或 7)时,catalina 日志文件中记录了严重的内存泄漏,该文件列出了我们应用程序中的所有 JAXB 类,两个不同的包中的两组。

我浏览过很多 google 和 Stack 溢出链接。我使用了 JProfiler,它告诉我 Tomcat 在不使用 Enum 时会保留它们,但这不应该是问题。 marshaller 或 unmarshaller 的所有实例都是在本地创建的,并设置为 null 以进行积极的 GC。我确保当 servlet 被销毁时 JAXBcontext 为空,并且在我的 contextDestroyed 中我运行 System.gc();为避免错误而建议。

但仍然会记录错误。 我在 Tomcat 演示文稿中看到这是已知错误,因为 JarURLConnection 锁是由 JAXBContext.newInstance() 创建的,显然这可以通过禁用缓存来避免,但这对我没有任何作用。 http://people.apache.org/~markt/presentations/2010-11-04-Memory-Leaks-60mins.pdf

关于如何在 Tomcat 上运行的 JAXB 中修复此内存泄漏的任何其他建议。

这是错误日志:

SEVERE: The web application [/myApplication] created a ThreadLocal with key of type [com.sun.xml.bind.v2.ClassFactory$1] (value [com.sun.xml.bind.v2.ClassFactory$1@6a724da1]) and a value of type [java.util.WeakHashMap] (value [{class my.package.model.layout.Element=java.lang.ref.WeakReference@7646bb9f, class my.package.model.layout.ScriptBeforeFileID=java.lang.ref.WeakReference@1dc80063, class my.package.model.layout.OutputProperty=java.lang.ref.WeakReference@359172db, class my.package.model.layout.Data=java.lang.ref.WeakReference@600ba356, class my.package.model.layout.InputProperty=java.lang.ref.WeakReference@1c10945d, class my.package.model.layout.ToPort=java.lang.ref.WeakReference@47c7410, class my.package.model.layout.ConfigFile=java.lang.ref.WeakReference@6a7c8bd, class my.package.model.layout.LayoutInstanceID=java.lang.ref.WeakReference@716bf3b4, class my.package.model.layout.ScriptAfterFunction=java.lang.ref.WeakReference@664ce898, class be.securit.trustbuilder.config.model.........}]) 
    but failed to remove it when the web application was stopped. 
Threads are going to be renewed over time to try and avoid a probable memory leak.
        17-sep-2013 15:21:45 org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks 

【问题讨论】:

    标签: java tomcat memory-leaks jaxb


    【解决方案1】:

    我有非常相似的问题。泄漏在 jaxb 上下文方法实现中:

    StringWriter writer = new StringWriter(200);
    JAXBContext context = JAXBContext.newInstance(objectClass);
    Marshaller marshaller = context.createMarshaller();
    marshaller.marshal(object, writer);
    

    此代码在每个 Web 服务请求上创建新实例。

    看到这个Memory leak in webservices with JAXB

    【讨论】:

      【解决方案2】:

      回顾所有不同的帖子后,我注意到提到将 JAXB 库放入 Tomcat 的共享库中。所以我从我的应用程序 WEB-INF/lib 中删除了 jaxb-impl-x.x.x.jar 并将其放入 [TomcatHome]/lib 中。现在一切都很好。不确定这是不是最好的,因为现在在 Tomcat 下安装时需要使用不同的方法。

      【讨论】:

      • 对我不起作用。无法看到移动的 jar 将如何运行,因为它们仍然以相同的方式加载...
      • 你好。如果 jar 驻留在应用程序范围内,并且重新部署了应用程序,则每次部署应用程序时都会加载 jar,则不会删除先前加载的类,因为它们持有弱引用。如果 jar 在共享库中,则不会发生这种情况。此实例仅在您可能多次重新部署应用程序的开发环境中使用。
      • 将 jar 移动到系统 Tomcat 路径并不能修复 jaxb-impl 中的错误。 Buggy 库仍然忘记清理线程局部变量。 Tomcat 检查代码仅在对象引用 Web 应用程序类加载器时发出警告,如果 $CATALINA_HOME/lib 引用中的 jaxb-impl 导致系统类加载器。
      猜你喜欢
      • 2011-02-24
      • 2014-12-25
      • 2015-12-27
      • 1970-01-01
      • 2012-08-20
      • 2012-08-06
      • 2013-07-29
      • 2015-06-04
      • 2014-04-03
      相关资源
      最近更新 更多