由于Spring单例导致的内存泄漏



由于缺乏理解,我在SINGLETON作用域(默认)中使用了一个spring bean。我用这个bean填充我的数据结构。数据结构是在init方法中填充的。在填充完数据结构之后,我就不再需要bean了。当我对应用程序进行可能的内存泄漏分析时,我发现这个单例对象占用了大量内存(它从数据库加载了大量数据)。

我猜,应用程序上下文保存所有单例bean的引用,直到它关闭。现在我变得明智了,我想解决这个问题。通过将bean的定义更改为PROTOTYPE,我认为我会使bean在超出范围后立即有资格进行垃圾收集,这是在它运行了init-method之后。我的问题是

这是处理这个问题的正确方法吗?2)如下面的xml片段所示。DataPopulator是一个bean,一旦它执行了它的init-method,我希望它被垃圾收集。但是它保留了对单例对象的引用。这如何不妨碍垃圾收集?理想情况下不应该是我所想的那样。征求你的意见
<bean class="com.foo.DataPopulator" init-method="loadDataOnStartUp" **scope="prototype"**>
    <property name="moService" ref="moServiceRef" />
</bean>
<osgi:reference id="moServiceRef" interface="com.foo.IMoDAO"/>

使用单例bean进行数据初始化并不罕见,我更喜欢单例bean而不是原型。内存使用可能是由于bean中的某些成员变量或静态引用保存了大量数据。试着将其重构为只使用在初始化完成后可以被垃圾收集的局部变量。

如果你只需要在应用程序上下文启动时执行一些方法来初始化moServiceRef中的数据,那么最好不要为DataPopulator创建bean。用@PostConstruct在你的moServiceRef中执行必要的方法。如果这不是一个选项,您可以尝试使用ApplicationListener并监听ContextRefreshedEvent来运行您的代码。

最新更新