tomcat 7.0和jax-ws 2.2.5内存泄漏

问题描述:

我正在用tomcat和jax-ws构建ws. 当我停止我的应用程序时,通常是从eclipse重新部署时,我会收到以下消息:

i'm building a ws with tomcat and jax-ws. when i stop my application, generally while redeploying from eclipse, i get this message:

25-mar-2012 16.21.16 com.sun.xml.ws.transport.http.servlet.WSServletDelegate destroy
INFO: WSSERVLET15: JAX-WS servlet destroyed
25-mar-2012 16.21.16 com.sun.xml.ws.transport.http.servlet.WSServletContextListener contextDestroyed
INFO: WSSERVLET13: JAX-WS context listener destroyed
25-mar-2012 16.21.16 org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
GRAVE: The web application [/xccm] created a ThreadLocal with key of type [com.sun.xml.ws.api.streaming.XMLStreamReaderFactory$Default$1] (value [com.sun.xml.ws.api.streaming.XMLStreamReaderFactory$Default$1@7edeaa13]) and a value of type [com.sun.xml.internal.stream.XMLInputFactoryImpl] (value [com.sun.xml.internal.stream.XMLInputFactoryImpl@4c700677]) 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. 

使用ClasspathHelper进行挖掘,我发现com.sun.xml.ws.api.streaming.XMLStreamReaderFactory$Default$1jaxws-rt.jar引用

diggin with ClasspathHelper i found that com.sun.xml.ws.api.streaming.XMLStreamReaderFactory$Default$1 is referenced by jaxws-rt.jar

但是我没有在代码中明确使用任何jax-ws类,除了:

however i do not explicitly use any jax-ws class in my code except:

import javax.jws.WebParam;
import javax.jws.WebService;
import javax.xml.bind.JAXBContext;

据我所知,tomcat加载了com.sun.xml.ws.transport.http.servlet.WSServlet(以及日志片段中的其他类).

and as far as i know tomcat loads com.sun.xml.ws.transport.http.servlet.WSServlet (and the other classes in log snippet).

知道如何解决此问题吗?

any idea how to solve this issue?

thx

您使用的库(JAX-WS实现)创建了一个线程本地线程,其密钥的类型由Web应用程序类加载器加载.

A library you use (the JAX-WS implementation) has created a thread local whose key is of a type that has been loaded by your web app class loader.

这意味着无法对Web应用程序类加载器进行垃圾回收,因为只有在没有强烈引用其类实例的情况下,才可以对类加载器进行垃圾回收.多次重新部署后,您的JVM将耗尽perm gen空间.

This means that the web app class loader cannot be garbage collected because a class loader can only be garbage collected if no instances of its classes are strongly referenced. After multiple re-deployments, your JVM will run out of perm gen space.

一个真正的解决方法是侦听Web应用程序的生命周期,并在关闭它时删除本地线程.但是,由于您不了解JAX-WS实现的内部,因此很难做到这一点.

A real fix would be to listen for the life cycle of your web application and remove the thread local when it is shut down. However, since you don't know the internals of the JAX-WS implementation, it will be difficult for you to do this.

另一种解决方案是将jaxws-rt.jar(以及可能与JAX-WS相关的其他JAR文件)添加到Tomcat安装的"lib"目录中.在这种情况下,它们将由通用类加载器加载,并且当您重新部署Web应用程序时将不会重新加载它们.

Another solution would be to add jaxws-rt.jar (and maybe other JAR files related to JAX-WS) to the "lib" directory of your Tomcat installation. In that case, they will be loaded by the common class loader and will not be reloaded when you re-deploy your web application.