有没有办法在关闭时使用 ContextListener 关闭 contextDestroyed() 方法中的所有 ThreadLocals(保存 Session 对象)?
Is there a way to close all the ThreadLocals (saving Session object) in contextDestroyed() method using ContextListener at the time of shutdown?
我在我的应用程序中遇到内存泄漏(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 应用程序停止时未能将其删除。线程将随着时间的推移而更新,以尝试避免可能的内存泄漏。
每次我们打开会话对象时,我都尝试关闭会话对象,但由于编码中使用的标准不足,我面临各种 Hibernate 级别的异常,因为某些对象被延迟获取,并关闭会话导致意外异常。
现在,如果可能的话,我正在尝试使用 contextListener 来实现同样的事情,而不用担心关闭每个会话对象。
我试过使用 System.gc() 但它似乎没有释放那些 ThreadLocal 对象。
能否请您提出一些在关闭时使用 Listener 或任何其他可能的方法来摆脱这些对象的方法?
网络请求完成后,您应该关闭 Hibernate 会话并将其从 ThreadLocal
中删除。
由于您似乎在生成响应时遇到了延迟加载问题(JSP?),您需要在 响应完全生成后执行此操作.
您可以在 Servlet 中做到这一点 Filter
。确保这是 在 您拥有的任何其他过滤器之前,因此会话将作为 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
}
}
}
}
我在我的应用程序中遇到内存泄漏(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 应用程序停止时未能将其删除。线程将随着时间的推移而更新,以尝试避免可能的内存泄漏。
每次我们打开会话对象时,我都尝试关闭会话对象,但由于编码中使用的标准不足,我面临各种 Hibernate 级别的异常,因为某些对象被延迟获取,并关闭会话导致意外异常。
现在,如果可能的话,我正在尝试使用 contextListener 来实现同样的事情,而不用担心关闭每个会话对象。
我试过使用 System.gc() 但它似乎没有释放那些 ThreadLocal 对象。
能否请您提出一些在关闭时使用 Listener 或任何其他可能的方法来摆脱这些对象的方法?
网络请求完成后,您应该关闭 Hibernate 会话并将其从 ThreadLocal
中删除。
由于您似乎在生成响应时遇到了延迟加载问题(JSP?),您需要在 响应完全生成后执行此操作.
您可以在 Servlet 中做到这一点 Filter
。确保这是 在 您拥有的任何其他过滤器之前,因此会话将作为 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
}
}
}
}