Spring bean范围''原型"和预定的方法内存泄漏

时间:2018-02-06 08:57:46

标签: java spring memory-leaks

    @Component
    @Scope("prototype")
    public class MessageHandller {
      .........................
     private static ConcurrentMap<String, Boolean> someObjectList = new ConcurrentHashMap<>(); 
      ....................................
       @Scheduled(fixedDelayString = "60000")
       public static void doSomething() {
          if(***) {
             someObjectList.add(**);
          } else {
             someObjectList.remove(**);
          }

       }
    }

那就说我有Class MessageHandller,它是带有Prototype范围的Spring Bean。在这个课程中我有预定的方法&#34; doSomething&#34;每60000毫秒运行一次。

我认为Scheduled方法可能会导致内存泄漏,因为它总是会对MessageHandler类进行引用,这是&#34; prototype&#34;范围,这意味着GC永远不会收集它?如果我错了,有人可以解释一下吗?

1 个答案:

答案 0 :(得分:0)

您必须明确区分使用@Schedule注释的方法和bean本身,当您注释方法并通过@EnableScheduling或xml替代启用调度功能时,spring将使用托管bean查找和搜索带注释的方法(注释为@Compenont,@ Service ...)在doc

中提及

如果您阅读有关Bean处理器ScheduledAnnotationBeanPostProcessor的信息。你会注意到它没有涉及这个过程的范围,并且无论bean父级的范围如何,TaskScheduler都会调用该方法

现在对于原型bean,文档提到:

  

与其他作用域相比,Spring不管理原型bean的完整生命周期:容器实例化,配置和组装原型对象,并将其交给客户端,没有该原型实例的进一步记录。因此,尽管无论范围如何都在所有对象上调用初始化生命周期回调方法,但在原型的情况下,不会调用已配置的销毁生命周期回调。客户端代码必须清理原型范围的对象并释放原型bean所持有的昂贵资源

因此,当没有对原型对象的引用时,它将像任何new object()隐式地被垃圾收集器一样销毁

为了清楚表明schedule方法的行为的生命周期与声明的bean不同,因为它的实现被其他bean管理器使用,就像TaskScheduler为此目的的任何{{1}}实现一样,< / p>

干杯