Spring Boot应用间歇性StackOverflowError问题排查求助
ThreadLocal 引发的 StackOverflowError 排查求助
我们正处于测试阶段,在某特定环境配置下出现如下错误:
Servlet.service() for servlet [dispatcherServlet] in context with path [/] threw exception [Handler dispatch failed: java.lang.StackOverflowError] with root cause at java.base/java.lang.ThreadLocal$SuppliedThreadLocal.initialValue(ThreadLocal.java:305) at java.base/java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:195) at java.base/java.lang.ThreadLocal.get(ThreadLocal.java:172) at java.base/java.lang.ThreadLocal$SuppliedThreadLocal.initialValue(ThreadLocal.java:305) at java.base/java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:195) at java.base/java.lang.ThreadLocal.get(ThreadLocal.java:172) at java.base/java.lang.ThreadLocal$SuppliedThreadLocal.initialValue(ThreadLocal.java:305) at java.base/java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:195) at java.base/java.lang.ThreadLocal.get(ThreadLocal.java:172) at java.base/java.lang.ThreadLocal$SuppliedThreadLocal.initialValue(ThreadLocal.java:305) at java.base/java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:195) at java.base/java.lang.ThreadLocal.get(ThreadLocal.java:172) at java.base/java.lang.ThreadLocal$SuppliedThreadLocal.initialValue(ThreadLocal.java:305) at java.base/java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:195) at java.base/java.lang.ThreadLocal.get(ThreadLocal.java:172) ... Error attributes: {timestamp=Wed Jan 22 15:50:31 UTC 2025, exception=java.lang.StackOverflowError, trace=java.lang.StackOverflowError
环境信息
- Spring Boot 3.3.2
- Spring Framework 6.1.11
- JDK 17
已排查情况
- 栈追踪中无业务代码调用,仅来自
java.base/java.lang包 - 排查该时段日志,未发现新线程启动、SQL数据库读写操作
- 未找到匹配的同类问题案例
可能原因与排查方向
1. ThreadLocal 初始化逻辑递归调用
从栈循环调用链可以明确:SuppliedThreadLocal的initialValue()方法中直接或间接调用了自身的get()方法,触发无限递归。
典型错误代码示例:
private static final ThreadLocal<String> BAD_THREAD_LOCAL = ThreadLocal.withInitial(() -> { // 错误:初始化时调用get()会再次触发initialValue() return BAD_THREAD_LOCAL.get(); });
排查项目中所有ThreadLocal.withInitial()的实现,检查是否存在这类递归逻辑。
2. 字节码增强工具篡改类逻辑
JDK 17 + Spring 6.x 环境下,若引入了第三方监控、AOP或诊断类组件,其字节码增强逻辑可能篡改了ThreadLocal相关类的执行流程,导致递归。
排查建议:
- 临时移除非必要的字节码增强依赖(如自定义监控、性能探针),测试问题是否复现
- 对比正常环境与问题环境的依赖清单,定位新增的可疑组件
3. JDK/Spring 版本兼容性问题
虽然使用的是稳定版本,但特定环境组合下可能存在未公开的兼容问题:
- 升级Spring Boot至同大版本的最新小版本(如3.3.x系列),验证问题是否消失
- 确认JDK为官方发行版,避免使用定制化修改的JDK包
4. 线程上下文类加载器异常
若线程上下文类加载器被非法篡改,可能导致ThreadLocal初始化时类加载逻辑异常,间接触发递归。可在问题环境中打印类加载器信息对比:
System.out.println("当前线程类加载器:" + Thread.currentThread().getContextClassLoader());
内容的提问来源于stack exchange,提问作者Radoslav Mitev
相关产品推荐
相关产品推荐

