2011-06-16 205 views
6

我正在使用Tomcat 6.0.18。在我的应用程序undeployemnt之后,HttpClient似乎持有对WebappClassLoader的引用,从而导致内存泄漏。sun.net.www.http.HttpClient在Tomcat中的内存泄漏6

经过一番调查,我发现解决方案Tomcat的7.0.6JreMemoryLeakPreventionListenerkeepAliveProtection属性。但是这种方法不适用于Tomcats 6(我已经定制了JreMemoryLeakPreventionListener,为了增加对这个属性的支持)。

有没有人有解决方案如何解决这个泄漏在Tomcat 6? Thanx!

+0

请发表您的解决方案作为一个答案,并将其标记为已接受,否则问题将保持开放。 – skaffman 2011-06-24 12:48:37

+0

@skaffman完成! – Igor 2011-06-24 13:29:18

回答

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>