我正在使用Tomcat 6.0.18.取消部署我的应用程序后,HttpClient似乎持有对WebappClassLoader的引用,从而导致内存泄漏.
经过一番调查,我在Tomcat 7.0.6,JreMemoryLeakPreventionListener中找到了keepAliveProtection属性的解决方案.但是这种方法不适用于Tomcats 6(我已经定制了JreMemoryLeakPreventionListener,以便添加对此属性的支持).
有没有人有解决方案如何在Tomcat 6中修复这个漏洞?
感谢名单!
解决方法
我找到了内存泄漏的解决方案.
必须执行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>