java - 有没有办法在关闭时使用 ContextListener 关闭 contextDestroyed() 方法中的所有 ThreadLocals(保存 Session 对象)?

标签 java session tomcat memory-leaks thread-local

我在我的应用程序中面临内存泄漏(TOMCAT v9),如下所示:

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

每次我们打开 session 对象时,我都尝试关闭 session 对象,但是由于编码中使用的标准不足,我面临着各种 Hibernate 级别的异常,因为某些对象是延迟获取的,关闭 session 会导致意外异常。

现在,如果可能的话,我正在尝试使用 contextListener 来实现同样的事情,而不用担心关闭每个 session 对象。

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

能否请您提出一些在关机时使用 Listener 或任何其他可能的方式摆脱这些对象的方法?

最佳答案

当 Web 请求完成时,您应该关闭 Hibernate session 并将其从 ThreadLocal 中删除。

由于您似乎在生成响应(JSP?)时遇到延迟加载问题,因此您需要在响应完全生成后执行此操作。

您可以在 Servlet Filter 中执行此操作。确保这是您拥有的任何其他过滤器之前,因此 session 将作为最后步骤关闭。

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

}

关于java - 有没有办法在关闭时使用 ContextListener 关闭 contextDestroyed() 方法中的所有 ThreadLocals(保存 Session 对象)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58107080/

相关文章:

java - server.port 和 server.context-path 在部署到 tomcat 时不生效

apache - 用于查找 Apache Tomcat 正在运行的端口的批处理脚本

java - 为什么条形图不执行?

ios - 如何保持两个不同设备之间的时钟 session ?

java - hibernate、jpa、c3p0 和警告 HHH000208

node.js - 如何使用 SessionID 从 RedisStore (connect-redis) 获取 session 数据?

c# - 在 ASP.NET 5 (MVC 6) 中使用 session

tomcat - 如何在自动缩放(多实例)Elastic Beanstalk (Tomcat) 应用程序 (AWS) 中配置数据文件?

java - 创建不带参数的方法和创建字符串参数的方法之间的区别?

java - 如何在 Linux 中软终止进程?