关于 Spring bean 容器中的作用域和垃圾回收

Posted

技术标签:

【中文标题】关于 Spring bean 容器中的作用域和垃圾回收【英文标题】:Regarding the scope and garbage collection in Spring bean container 【发布时间】:2011-12-07 16:45:29 【问题描述】:

我是 Spring 新手,目前正在我的一个项目中使用它。我了解到 Spring 容器包含所有 bean,所有 bean 的范围默认为"singleton"。我可以在application-context.xml 文件中或使用注释@Scope 更改范围。 我还了解到,如果一个类具有"prototype" 的范围,Spring 容器将在需要时实例化该类的一个新对象。

我不明白的是:垃圾收集是如何处理的。如果不再需要创建的对象,它们是否会被垃圾回收,或者它们仍会保留在容器中。显然,我不希望创建和保留很多对象以保持低内存使用率。

【问题讨论】:

【参考方案1】:

来自 Spring 文档 (3.5.2 The prototype scope):

与其他范围相比,Spring 不管理原型 bean 的完整生命周期:容器实例化、配置和以其他方式组装原型对象,并将其交给客户端,使用没有该原型实例的进一步记录

简单地说——一旦你创建并获得了对prototype作用域bean的引用,它就是JVM中唯一存在的引用。一旦此引用超出范围,该对象将被垃圾回收:

void bar() 
  Object foo = ctx.getBean("foo")

离开bar() 方法的那一刻,没有任何其他对foo 新实例的引用,这意味着它有资格进行垃圾回收。这个模型的结果是:

因此,尽管 initialization 生命周期回调方法在所有对象上都被调用,而不管范围如何,但在原型的情况下,配置的销毁生命周期回调不会被调用。

【讨论】:

我试图理解这一点。那么它是否使 @PreDestroy 与原型 bean 无关? @Larsen 是的,就是这个意思。【参考方案2】:

容器不会保留对实例化 bean 的引用,使用它们的代码会保留。

如果没有其他内容(大致)引用该 bean,则它符合 GC 条件。

【讨论】:

非常感谢您的快速回复

以上是关于关于 Spring bean 容器中的作用域和垃圾回收的主要内容,如果未能解决你的问题,请参考以下文章

[Spring5]IOC容器_Bean管理_bean的作用域和bean的生命周期

Spring bean的作用域和生命周期

Spring:玩转bean的作用域和自动装配!

Bean的作用域和生命周期

Bean的作用域和生命周期

Bean的作用域和生命周期