When is an object of prototype bean gets garbage collected when we use proxy mode for Scope Protype in Spring Boot

prnjn :

when will a prototype bean get garbage collected if we use proxy mode for scope prototype for a class in Spring boot, is it handled by Spring?

when the object of MyClassB will get garbage collected in below example or is it leading to a memory leak?

 @Service
    public class MyClassA {

        @Autowired
        private MyClassB myClassB;

        public String findMydata(String input) {

            String myData = myClassB.getSomeData(input);    
            return myData;
        }
    }

Below is the class with scope prototype which is used by above class

@Service
@Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE,
       proxyMode=ScopedProxyMode.TARGET_CLASS)
public class MyClassB {

        MyPojoClassA mypojoA = null;
        MyPojoClassB mypojoB = null;     

    @Autowired
    private MyClassC myClassC;

    @Autowired
    private myClassD myClassD;

    public String getSomeData(String input) {
        String SomeData = "";

            myMethodA(input);

            // makes call to external service for data  
        SomeData = myClassC.getSomeData(mypojoA.getSomething());
        myMethodB(mypojoA.getSomeOthervalue());

        if(SomeData.isBlank()){
                // retrieve the data from database.
            SomeData = myClassD.getSomeData(mypojoB.getSomething());
        }
        return SomeData;
    }

        private void myMethodA(String input){
           // process and set values in mypojoA
        }
        private void myMethodB(String input){
           // process and set values in mypojoB
        }
}

The usage and assigning values to different fields of myPojoA and myPojoB is done multiple times by calling different private methods inside method getSomeData. here in code sample I have not made those calls for simplicity, but have to show that there are two instance level reference variables of two classes being used.

Ken Chan :

If an object is not referenced / used by other objects, it is eligible for GC. (Source , see the section Describing Garbage Collection).

In your example , though you are injecting a prototyped MyClassB into an singleton MyClassA , MyClassA will always access to the same MyClassB instance mainly because injection of MyClassB into MyClassA will only happen once when instantiating MyClassA . This behaviour is well explained in the docs as follows:

When you use singleton-scoped beans with dependencies on prototype beans, be aware that dependencies are resolved at instantiation time. Thus, if you dependency-inject a prototype-scoped bean into a singleton-scoped bean, a new prototype bean is instantiated and then dependency-injected into the singleton bean. The prototype instance is the sole instance that is ever supplied to the singleton-scoped bean.

However, suppose you want the singleton-scoped bean to acquire a new instance of the prototype-scoped bean repeatedly at runtime. You cannot dependency-inject a prototype-scoped bean into your singleton bean, because that injection occurs only once, when the Spring container instantiates the singleton bean and resolves and injects its dependencies.

As MyClassA is a singleton , it always exist during the application runs. It means its dependencies (i.e MyClassB) will always be used by that MyClassA instance and they will never be eligible for GC.

If you want to create a new MyClassB instance whenever MyClassA accesses MyClassB , you can use one of the following technique describe here. Just make sure the new MyClassB instance will never be assigned to the fields of some singleton bean , then it will be eligible to be GC when that method exit. Something like:

@Service
public class MyClassA {

        @Autowired
        private Provider<MyClassB> myClassB;

        public String findMydata(String input) {
            MyClassB classB = myClassB.get(); 
            String myData = classB.getSomeData(input);    
            return myData;
        }
}

I am using technique 5 described at this.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=305414&siteId=1