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),会对系统产生什么影响?

相关推荐
瀚高PG实验室42 分钟前
瀚高数据库V9.0.5数据脱敏完整配置步骤
jvm·数据库·postgresql·瀚高数据库
EXI-小洲1 小时前
Spring AI (第二章)大模型对话上下文记忆
java·人工智能·spring
阿里云基础软件2 小时前
一句话看透 JVM,SysOM 诊断 Skill 新增 Java 应用诊断能力
java·开发语言·jvm·人工智能·操作系统·sysom 诊断 skill
Wang's Blog2 小时前
Java框架快速入门: Spring Security+OAuth2之自动化集成测试
java·spring·自动化
Zzzzmo_2 小时前
SpringBoot 日志
java·spring boot·spring
小白说大模型2 小时前
《FDE前沿部署工程师实战教程》企业 Agent 项目实战:从需求分析到 PoC 落地
人工智能·spring·机器学习·自然语言处理·chatgpt·数据挖掘·需求分析
wuminyu2 小时前
Kafka的写入延迟与磁盘IO抖动原理分析
java·linux·c语言·jvm·c++
fallwind_of_july3 小时前
JVM 频繁 Full GC 排查思路:从原理到工具实战
jvm
写后端的胖头鱼3 小时前
一文讲懂JVM与调优
jvm·后端·算法·架构·jvm调优
Wang's Blog3 小时前
Java框架快速入门: Spring Security+OAuth2之深度定制UserDetailsService与密码无缝升级
java·开发语言·spring