7

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

我经历了很多谷歌和堆栈溢出链接。我使用了 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 
4

2 回答 2

11

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

于 2013-09-17T14:24:31.863 回答
4

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

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

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

使用 JAXB 在 Web 服务中查看此内存泄漏

于 2015-12-02T13:57:02.457 回答