文章目录核心结论**会但前提是它必须变得“不可达”。**1. Singleton Bean单例通常与容器同生死2. Prototype Bean多例管生不管死3. 决定 Bean 被回收的具体条件总结对照表核心结论会但前提是它必须变得“不可达”。Bean 本质上就是堆内存里的一个普通的 Java 对象。JVM 的垃圾回收GC逻辑对它依然生效但 Spring 容器ApplicationContext的存在直接干预了它的“生命长度”。1. Singleton Bean单例通常与容器同生死对于单例 BeanJVM 回收它的阻碍在于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 回收必须同时满足以下两个“断开”Spring 容器断开引用对于单例必须销毁容器或手动从容器中剔除 Bean。对于多例创建完成即已断开。业务代码断开引用如果你在代码里把一个 Bean 赋值给了一个静态变量Static或者放进了一个长生命周期的集合里那么即使 Spring 容器关了JVM 依然无法回收它。这就是常见的内存泄漏来源。总结对照表Bean 作用域Spring 容器是否持有引用谁决定它何时被回收Singleton是存放在单例缓存池中Spring 容器。容器关闭引用才释放。Prototype否创建完就撒手你的代码。你不用了它就被回收。一句话总结Bean 只是披着 Spring 外壳的对象能不能回收全看JVM 的引用链上还有没有它的位置。单例 Bean 就像是住进了“养老院”容器只要养老院不倒闭它就一直活着。既然说到单例 Bean 很难被回收你觉得如果在单例 Bean 里面定义了一个巨大的成员变量比如一个装了几百万条数据的ArrayList会对系统产生什么影响