sun.net.www.http.HttpClient在Tomcat 6中发生内存泄漏

时间:2011-06-16 08:46:13

标签: tomcat memory-leaks httpclient

我正在使用 Tomcat 6.0.18 。取消部署我的应用程序后, HttpClient 似乎持有对 WebappClassLoader 的引用,从而导致内存泄漏。

经过一些调查,我在 Tomcat 7.0.6 JreMemoryLeakPreventionListener中找到了 keepAliveProtection 属性的解决方案。但是这种方法不适用于 Tomcats 6 (我已经定制了JreMemoryLeakPreventionListener,以便添加对此属性的支持)。

有没有人有解决方案如何在Tomcat 6中修复此漏洞? 感谢名单!

1 个答案:

答案 0 :(得分:8)

我找到了内存泄漏的解决方案。

必须执行ServletContextListener,如下所示:

package org.example;

public class MyServletContextListener implements ServletContextListener {

    public void contextDestroyed(ServletContextEvent sce) {
         tomcatLeakPreventionForHttpClient();
    }

    private void tomcatLeakPreventionForHttpClient() {
        try {
            final Field kac = HttpClient.class.getDeclaredField("kac");
            kac.setAccessible(true);
            final Field keepAliveTimer = KeepAliveCache.class.getDeclaredField("keepAliveTimer");
            keepAliveTimer.setAccessible(true);

            final Thread t = (Thread) keepAliveTimer.get(kac.get(null));
            if(t.getContextClassLoader() == Thread.currentThread().getContextClassLoader()) {
                t.setContextClassLoader(ClassLoader.getSystemClassLoader());
            }
        } catch(final Exception e) {
        }
    }

    public void contextInitialized(ServletContextEvent event) {
    }

}

当然,要在 web.xml 中注册监听器:

  <listener>
    <listener-class>org.example.MyServletContextListener</listener-class>
  </listener>