Tomcat9服务器内存泄漏是否引发系统重启及解决方案咨询
应用日志中出现内存泄漏提示,同时系统发生重启,需确认该内存泄漏是否为系统重启的原因,并获取对应的解决办法。
应用日志
2024年5月16日 01:00:57.374 警告 [Thread-4]
org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads
Web应用[admin-api]似乎启动了一个名为[boundedElastic-17]的线程,但未正确停止它。这极有可能造成内存泄漏。线程堆栈跟踪:
java.base@11.0.22/jdk.internal.misc.Unsafe.park(Native Method)
java.base@11.0.22/java.util.concurrent.locks.LockSupport.park(LockSupport.java:194)
java.base@11.0.22/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2081)
java.base@11.0.22/java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1170)
java.base@11.0.22/java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:899)
java.base@11.0.22/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1054)
java.base@11.0.22/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1114)
java.base@11.0.22/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
java.base@11.0.22/java.lang.Thread.run(Thread.java:829)
服务器日志
重启 系统启动 5.15.0-1064-azur 2024年5月16日 01:01 仍在运行 重启 系统启动 5.15.0-1063-azur 2024年5月10日 01:03 - 01:00 (5天23小时57分) 重启 系统启动 5.15.0-1061-azur 2024年4月21日 23:22 - 01:03 (18天1小时40分) 重启 系统启动 5.15.0-1060-azur 2024年4月18日 22:19 - 23:22 (3天1小时2分) 重启 系统启动 5.15.0-1060-azur 2024年4月11日 22:18 - 22:19 (7天1分) 重启 系统启动 5.15.0-1059-azur 2024年3月21日 22:14 - 22:18 (21天4分) 重启 系统启动 5.15.0-1058-azur 2024年3月11日 11:27 - 22:14 (10天10小时46分) 重启 系统启动 5.15.0-1058-azur 2024年3月11日 10:12 - 11:27 (1小时14分) 重启 系统启动 5.15.0-1058-azur 2024年3月8日 22:00 - 10:12 (2天12小时12分) 重启 系统启动 5.15.0-1057-azur 2024年3月6日 09:47 - 22:00 (2天12小时12分) 重启 系统启动 5.15.0-1057-azur 2024年3月1日 08:38 - 09:47 (5天1小时9分) 重启 系统启动 5.15.0-1057-azur 2024年2月28日 21:35 - 18:23 (20小时47分) 重启 系统启动 5.15.0-1057-azur 2024年2月28日 15:15 - 21:35 (6小时20分)
内存泄漏与系统重启的关联判断
- 时间线高度重合:内存泄漏警告出现在5月16日01:00:57,系统重启在01:01,存在关联可能性,但无法直接确认因果关系。
- 常规影响范围:这类Tomcat线程泄漏通常仅导致Web应用类加载器无法回收,JVM内存缓慢上升,一般不会直接触发系统级重启。
- 系统频繁重启的潜在原因:从日志看2月到5月多次重启,更可能是系统层面问题,比如:
- Linux OOM Killer触发(系统内存耗尽时强制终止进程)
- 硬件故障、系统服务崩溃
- 定时重启任务或自动化运维操作
- 验证建议:
- 查看系统日志(如
/var/log/syslog),搜索关键词Out of memory确认是否存在OOM Killer记录 - 监控JVM内存使用趋势,确认是否存在持续飙升导致JVM崩溃的情况
- 查看系统日志(如
内存泄漏问题的修复方案
针对boundedElastic-17线程未停止的问题,这多是Reactor框架(Spring WebFlux常用)线程池未正确关闭导致的,修复步骤如下:
- 代码层面修复:
- 若使用Spring WebFlux,确保
Scheduler或自定义线程池在应用关闭时被销毁。可实现DisposableBean接口,在destroy()方法中调用shutdown()或dispose()释放资源。 - 示例代码:
@Component public class ThreadPoolCleanup implements DisposableBean { @Autowired private Scheduler boundedElasticScheduler; @Override public void destroy() throws Exception { boundedElasticScheduler.dispose(); } }
- 若使用Spring WebFlux,确保
- Tomcat配置优化:
- 在
context.xml中添加<Context clearReferencesStopThreads="true"/>,强制Tomcat在应用卸载时停止未清理的线程。 - 升级Tomcat到较新版本,新版本对线程泄漏的处理机制更完善。
- 在
- 验证与监控:修复后重启应用,观察日志是否不再出现该警告,同时通过JVM监控工具(如JConsole)跟踪内存回收情况,确认泄漏问题解决。
内容的提问来源于stack exchange,提问作者Spacewalker_vir

