本文介绍了通过从内存中清除Spring Prototype Bean来澄清情况的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想了解是否应该由我自己从内存中手动清理原型beans .

I would like to understand whether I should clean prototype-beans from memory manually by myself.

在Spring文档中,您可以看到:客户端代码必须清除原型作用域内的对象并释放原型bean所拥有的昂贵资源."

In the Spring documentation you can see:"The client code must clean up prototype-scoped objects and release expensive resources that the prototype bean(s) are holding."

因此,看来您应该自己清理原型bean.

So from this it seems that you should clean prototype-beans by yourself.

但是.

我正在使用VisualVM 内存分析器.我创建了许多原型bean.您可以看到它们的 51 个实例.

I'm using VisualVM memory profiler.I have created a number of prototype-beans. You can see 51 instances of them.

然后您会看到垃圾收集器清理内存的情况-所有原型bean都已清除.

Then you can see the situation when the garbage collector clean the memory - all prototype-beans were cleared.

那么任何人都可以澄清情况吗?是由垃圾收集器成功清除了原型bean,还是应该手动清除它们(如果是,如何清除)?

So can anyone clarify the situation? Are prototype-beans cleared successfully by garbage collector or we should clear them manually (if yes, how)?

添加.有些人要求显示创建原型bean的代码.实际上,我没有任何意义,因为在特定示例中,我仅将它们创建为测试,并且与从内存中清除原型bean的实际情况无关.开发人员可以通过不同的方式来创建原型bean,但是它们的未来行为不或不应该依赖于创建方法.

Addition.Some guys asked to show the code of creating the prototype-beans. Actually I don't see any sense in this because in the particular example I am creating them only as a test and this don't concern the actual situation with cleaning prototype-beans from memory. Developers can create prototype-beans by different ways but the future behaviour of them doesn't or shouldn't depend on a creation method.

在我们的真实项目中,我们有超过400个被标注为Prototype-beans的组件,我可以看到相同的行为.我已经向我们的系统发出了许多请求,通过VisualVM看到了许多创建的原型bean,然后在垃圾回收器清理内存之后,所有原型bean都被清除了.

In our real project where we have more then 400 components annotated as Prototype-beans I can see the same behavior. I have made a number of requests to our system, see a number of created prototype beans through VisualVM, then after garbage collector clean the memory all prototype beans become cleared.

我展示测试代码只是希望那些询问此问题的人能提供有关实际行为的一些有意义的信息,而不仅仅是关于这个特定测试bean创建的空话.

I show the testing code just in the hope that those who asked about this will give some senseful information about the real behavior not just empty words about this particular test bean creation.

为示例创建原型bean的测试:

for(int i=0;i<10;i++){
        Prototype1 prototype1=applicationContext.getBean(Prototype1.class);
        Prototype2 prototype2=applicationContext.getBean(Prototype2.class);

        prototype1.test1();
        prototype2.test2();
}

原型Bean的测试示例:

@Service
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class Prototype1 {

    private int number;

    public Prototype1() {
        System.out.println("Prototype1 was created.");
    }

    public void test1(){

    }

}

推荐答案

创建原型bean之后;您要为其生命周期负责.

Once you create a prototype bean; you are responsible for its lifecycle.

一旦您没有对该bean的引用,它就消失了.原型bean和作用域bean之间的唯一真正区别是容器如何对其进行管理.

Once you have no reference to that bean it is gone. The only real differences between a prototype bean and a scoped bean is how it is managed by the container.

在单元测试中,您不会依赖于容器来为您提供这些bean,而只是您自己即可对其进行更新.

In a unit test you would not rely on the container to give you these beans you would simply new them yourself.

因此,要真正回答您的问题,如果您允许原型对象被应用程序取消引用,则jvm的默认行为将消除这些bean.

So to really answer your question, if you allow the prototype object to be dereferenced by your application, the jvm's default behavior will eliminate these beans.

 public class Example {

    @Scope("prototype")
    public static class SomePrototypeBean{

    }

    @Singleton
    public static class MySingleton{

        @Bean
        private SomePrototypeBean somePrototypeBean;

    }

    public static void main(String[] args){
       // context creation code goes here

       // singleton is created, a prototype injected
       context.getBean(MySingleton.class);
       // NOTE: the prototype injected will last for as long as MySingleton has reference
       // my singleton will exist for as long as the context has reference

       doStuff(context);
       //prototype bean created in the method above will be GCed
    }

    public static void doStuff(Context context){
        context.getBean(MyPrototypeBean.class);
        //since we literally are doing nothing with this bean, it will be
        // marked for garbage collection
    }

}

这篇关于通过从内存中清除Spring Prototype Bean来澄清情况的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-11 07:07