You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 20:26:09