Weblogic大量java.util.TimerThread.run的TIMED_WAITING线程及OOM问题咨询
java.lang.OutOfMemoryError: unable to create new native thread 问题排查结论
大量TimerThread线程堆积原因
你观察到的数千个TIMED_WAITING状态的TimerThread线程,直接来源于org.cfg4j.source.reload.strategy.PeriodicalReloadStrategy的初始化逻辑:
- 第二种OOM调用栈已经明确,每创建一个
PeriodicalReloadStrategy实例,其构造函数都会新建一个独立的java.util.Timer实例,每个Timer会启动一个专属的后台TimerThread线程。只要Timer实例没有被显式调用cancel()方法,该线程就会一直处于TIMED_WAITING状态挂起,不会被GC回收。 - 根本原因是应用代码存在重复初始化cfg4j配置源、重复创建
PeriodicalReloadStrategy实例的逻辑:比如每次请求触发、每次读取配置时都新建cfg4j上下文实例,没有全局复用配置源和重载策略,运行时间越长累计的Timer线程越多。 - 该问题和Weblogic服务器自身无关,属于应用对第三方依赖cfg4j的使用不当导致的线程资源泄漏。
问题定位方法
- 全局搜索应用代码中
PeriodicalReloadStrategy的实例化位置,查看是否存在循环调用、请求级新建实例的错误逻辑 - 测试环境可在
PeriodicalReloadStrategy构造函数处加断点或调用栈打印日志,确认实例创建的触发链路
修复建议
- 全局复用cfg4j配置实例和重载策略:确保应用整个生命周期内只初始化一次
PeriodicalReloadStrategy,不要每次使用配置都新建实例 - 如果业务场景确实需要动态创建重载策略,用完必须显式调用
PeriodicalReloadStrategy.shutdown()方法,销毁内部持有的Timer实例,释放对应的线程资源 - 你提供的第一种OOM调用栈对应Spring的
SimpleAsyncTaskExecutor,该执行器默认每次提交任务都会新建线程,没有线程池复用逻辑,如果@Async注解绑定了该执行器,也会加剧线程资源耗尽风险,建议替换为ThreadPoolTaskExecutor,设置合理的核心线程、最大线程数上限,避免无限创建线程。
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

