Tomcat 6 中的 sun.net.www.http.HttpClient 内存泄漏

发布于 2024-11-15 17:07:36 字数 539 浏览 1 评论 0原文

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

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

有人有解决 Tomcat 6 中这个泄漏的解决方案吗? 谢谢!

I'm using Tomcat 6.0.18. After undeployemnt of my app, HttpClient appears to be holding a reference to WebappClassLoader, hence causing the memory leak.

After some investigation, I've found solution in Tomcat 7.0.6, JreMemoryLeakPreventionListener with keepAliveProtection attribute. But this approach is not working with Tomcats 6 (I've customized JreMemoryLeakPreventionListener, in order to add support for this attribute).

Does anybody have a solution how to fix this leak in Tomcat 6?
Thanx!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

如果没结果 2024-11-22 17:07:36

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

必须实现 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>

I've found the solution for memory leak.

One must make implementation of ServletContextListener, as following:

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) {
    }

}

and, of course, to register listener in web.xml:

  <listener>
    <listener-class>org.example.MyServletContextListener</listener-class>
  </listener>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文