Bean 会被 JVM 回收吗?

文章目录

核心结论:会,但前提是它必须变得"不可达"。

Bean 本质上就是堆内存里的一个普通的 Java 对象。JVM 的垃圾回收(GC)逻辑对它依然生效,但 Spring 容器(ApplicationContext)的存在直接干预了它的"生命长度"。


1. Singleton Bean(单例):通常与容器同生死

对于单例 Bean,JVM 回收它的阻碍在于 Spring 容器本身

  • 强引用的拉扯 :Spring 容器内部维护着一个单例池(通常是一个 ConcurrentHashMap),用来存放所有的单例 Bean 实例。
  • GC 路径 :在 JVM 的 GC 算法(如可达性分析)中,ApplicationContext 通常作为一个 GC Root 或者被 GC Root 引用。只要容器还在运行,它就一直"拉着"这些 Bean 的引用。
  • 回收时机只有当容器被关闭(Close)时,容器才会清空单例池,释放对这些 Bean 的引用。此时,如果没有其他业务代码(比如静态变量)还拽着这个 Bean,它才会变成"垃圾",在下一次 GC 时被清理。

2. Prototype Bean(多例):管生不管死

多例 Bean 的待遇和单例完全不同:

  • Spring 的放手 :Spring 容器只负责多例 Bean 的创建、初始化和装配。一旦它把这个对象交到你手中,它就不再持有这个对象的任何引用了。
  • 回收时机 :它就像你直接 new 出来的普通对象一样。一旦你的业务逻辑执行完毕,不再有任何变量指向它,它就会立即变成不可达状态,静候 JVM 的 GC 回收。

3. 决定 Bean 被回收的具体条件

一个 Spring Bean 要想被 JVM 回收,必须同时满足以下两个"断开":

  1. Spring 容器断开引用
  • 对于单例:必须销毁容器或手动从容器中剔除 Bean。
  • 对于多例:创建完成即已断开。
  1. 业务代码断开引用
  • 如果你在代码里把一个 Bean 赋值给了一个静态变量(Static) ,或者放进了一个长生命周期的集合 里,那么即使 Spring 容器关了,JVM 依然无法回收它。这就是常见的内存泄漏来源。

总结对照表

Bean 作用域 Spring 容器是否持有引用 谁决定它何时被回收?
Singleton 是(存放在单例缓存池中) Spring 容器。容器关闭,引用才释放。
Prototype 否(创建完就撒手) 你的代码。你不用了,它就被回收。

一句话总结:

Bean 只是披着 Spring 外壳的对象,能不能回收,全看 JVM 的引用链上还有没有它的位置。单例 Bean 就像是住进了"养老院"(容器),只要养老院不倒闭,它就一直活着。

既然说到单例 Bean 很难被回收,你觉得如果在单例 Bean 里面定义了一个巨大的成员变量(比如一个装了几百万条数据的 ArrayList),会对系统产生什么影响?

相关推荐
MuYiLuck1 小时前
01-spring-boot-autoconfig-principle
java·spring·maven·自动配置
云烟成雨TD1 小时前
Spring AI Alibaba 1.x 系列【47】状态图定义:StateGraph 源码解析
java·人工智能·spring
6190083361 小时前
spring中 HTTP 请求常见格式
java·spring·http
阿维的博客日记1 小时前
传统 Spring XML 配置 vs Spring Boot Starter 对比文档
xml·spring boot·spring
liann1192 小时前
Agent 内存马禁止 Attach JVM
java·jvm·安全·网络安全·系统安全·网络攻击模型·信息与通信
代码漫谈2 小时前
JVM 参数调优:Spring Boot与JDK新特性的最佳结合
java·jvm·spring boot
海兰2 小时前
【第39篇】spring-ai-alibaba-graph-example学习路径概览
人工智能·spring boot·学习·spring·spring ai
2401_898717662 小时前
HTML5中SVG原生动画标签Animate的基础用法
jvm·数据库·python
Don.TIk2 小时前
天机の学堂
java·spring boot·spring·maven·mybatis