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

Spring Rest API Controller中的静态变量是否会引发内存泄漏?

关于Spring Controller静态变量是否导致内存泄漏的问题解答

参考代码

@RestController
@RequestMapping("/v1")
public class TransactionController {
    final static Logger logger = LogManager.getLogger(TransactionController.class);
    static Gson gson = new Gson();

    @RequestMapping(value = "/create-transaction", method = RequestMethod.POST, produces = "application/json")
    public @ResponseBody
    String createTransaction(@RequestBody String json, HttpServletRequest request, HttpServletResponse response) {
        long startTime = System.currentTimeMillis();
        try{
           ...
        } catch (Exception ex) {
            logger.error(LogAdapter.logToLog4jException(startTime, request, "", json, gson.toJson("output here"), ex.toString()), ex);
        }
    }
}

核心问题解答

静态变量是否会每次接口调用重新创建?

不会。Java中被static修饰的类成员属于类本身,仅在类第一次被类加载器加载时初始化1次,整个JVM运行生命周期内只会存在一份实例,所有接口请求、类实例都会共享该静态变量,不存在重复创建的问题。

是否推荐改为局部声明使用?

不推荐,原因如下:

  • Logger的行业通用最佳实践就是声明为private static final的类静态变量,改为局部声明反而需要每次请求都重新获取Logger实例,无意义且会产生额外性能开销。
  • 无参构造的Gson实例本身是线程安全的,只要没有为Gson配置带状态的自定义TypeAdapter、序列化/反序列化器,全局复用单例Gson实例是性能最优的写法。如果改为局部声明每次调用都new Gson(),会重复创建对象,增加不必要的GC压力。

内存泄漏排查方向

你当前的这两个静态变量写法是常规合理写法,不会导致内存泄漏,建议从以下方向排查泄漏原因:

  • 检查是否有ThreadLocal变量使用后未调用remove()方法清理:Spring Boot内置的Tomcat线程池会复用工作线程,若请求处理过程中往ThreadLocal存入内容后未清理,会导致线程绑定的对象一直无法被回收,产生泄漏。
  • 检查其他静态集合类(如static修饰的List、Map)是否存在持续写入元素但未做清理、淘汰机制的情况,静态集合的生命周期和JVM一致,存入的对象会一直被持有无法释放。
  • 检查是否有IO流、数据库连接、网络连接等外部资源使用完成后未正常关闭释放。
  • 检查是否存在自定义的对象缓存、第三方组件缓存未设置容量上限和淘汰策略。

内容的提问来源于stack exchange,提问作者ghost123

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 21:24:04