java - 有没有办法在关闭时使用 ContextListener 在 contextDestroyed() 方法中关闭所有 ThreadLocals(保存 Session 对象)?
问题描述
我在我的应用程序中面临关于 Threadlocals 对象的内存泄漏(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 应用程序停止时未能将其删除。线程将随着时间的推移而更新,以尝试避免可能的内存泄漏。
每次打开会话对象时,我都尝试关闭会话对象,但是由于缺乏编码中使用的标准,我面临着各种休眠级别的异常,因为某些对象是延迟获取的,并且关闭会话会导致意外异常。
现在,如果可能,我正在尝试使用 contextListener 来实现相同的目的,而不必担心关闭每个会话对象。
我试过使用 System.gc() 但它似乎没有释放那些 ThreadLocal 对象。
您能否建议一些方法在关闭时使用 Listener 或任何其他可能的方式摆脱这些对象?
解决方案
您应该关闭 Hibernate 会话并将其从ThreadLocal
Web 请求完成时删除。
由于您在生成响应(JSP?)时似乎遇到了延迟加载问题,因此您需要在完全生成响应后执行此操作。
您可以在 Servlet 中执行此操作Filter
。确保这是在您拥有的任何其他过滤器之前,因此会话作为最后一步关闭。
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 - 如何从 Recylerview 中删除 Edittext 值并在活动中更新 textview
- python - 发送具有“pedro”的消息后,发送函数循环。没有 .lower 可以正常工作,但是当我将其添加回来时,它是否开始循环
- db2 - 基本命令 (db2level) 未免费运行 Db2 Community Edition 11.5.5(最新)
- tensorflow - 将 keras 函数式 API 与 TFRecordDataset 一起使用
- astropy - 尝试使用 WCSaxes 和 Astroquery 绘制 TESS 和 2MASS 图像
- javascript - 每次绘制数据表都会扩展
- doxygen - 使用 Doxygen 生成 PDF
- javascript - 图像对齐
- javascript - 从 Tab Chrome Extension Manifest v3 获取数据
- c - 包括头文件中定义的枚举