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

相关推荐
雷一言说2 小时前
Spring AI 2.0 Agent Skills 接入
spring
萧瑟余晖2 小时前
Spring Cloud综合实战与架构选型详解
spring·spring cloud·架构
骑着蜗牛撵大象3273 小时前
四种库收进一个SQL编辑器(下):跨库取数、方言对齐与四库巡检的落地拆解
jvm·数据库·sql·编辑器·数据迁移·跨库查询
萧瑟余晖4 小时前
Spring Cloud Alibaba生态整合详解
spring·spring cloud·面试
专业程序开发源18 小时前
springboot欧缇蔓月子中心管理系统82697-计算机课程设计、毕业设计
java·spring boot·后端·python·spring·django·课程设计
小溪学编程20 小时前
将 Bean 放入 Spring 容器中的方式有哪些?
java·后端·spring
需要82621 小时前
容器化 Java:镜像瘦身与 JVM 容器感知(cgroup)
java·开发语言·jvm
Vegetable_xu1 天前
Spring Bean 循环依赖:为什么有时能过、有时启动就挂
java·spring·mybatis
开开心心_Every1 天前
免费压缩软件WinRAR无弹窗、广告干扰
java·开发语言·前端·spring·智能手机·word·winrar
YDS8291 天前
Small Spring IOC篇:应用上下文实现和Bean的扩展
java·后端·spring