在关闭时是否可以使用ContextListener关闭contextDestroyed()方法中的所有ThreadLocals(保存会话对象)?

问题描述 投票:0回答:1

我在应用程序中遇到有关Threadlocals对象的内存泄漏(TOMCAT v9),如下所示:

25-Sep-2019 17:40:34.752严重[Thread-10] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks Web应用程序[]创建了一个键为[java.lang.ThreadLocal]类型的ThreadLocal [java.lang.ThreadLocal@7c606bab])和类型为[org.hibernate.internal.SessionImpl]的值(值[SessionImpl(56310373)]),但在Web应用程序停止时无法删除它。线程将随着时间的流逝而更新,以尝试避免可能的内存泄漏。

我试图每次打开会话对象时都关闭会话对象,但是由于缺少编码中使用的标准,我面临着各种Hibernate级别的异常,因为有些对象被延迟获取,并且关闭会话会导致意外情况例外。

现在,如果可能的话,我正在尝试使用contextListener实现相同的目的,而不必担心关闭每个会话对象。

我尝试使用System.gc(),但似乎没有释放那些ThreadLocal对象。

您能否建议在关闭时使用侦听器或其他任何可能的方法摆脱这些对象的方法?

java session tomcat memory-leaks thread-local
1个回答
1
投票

您应该关闭Hibernate会话,并在完成Web请求后将其从ThreadLocal中删除。

由于您似乎在生成响应(JSP)时延迟加载存在问题,因此需要after响应已完全生成。

您可以在Servlet Filter中执行此操作。确保这是before您拥有的任何其他过滤器,因此会话将作为last步骤关闭。

public final class SessionCloseFilter implements Filter {
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    public void destroy() {
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
        try {
            chain.doFilter(request, response);
        } finally {
            try {
                // Close and remove session here
            } catch (Exception e) {
                // Log but don't throw the exception
            }
        }
    }

}

© www.soinside.com 2019 - 2024. All rights reserved.