I am new to Spring framework. I have been confused about the concept of singleton in Spring and it's garbage collection. I have read many questions and articles to get the answer to my question that how Spring Singleton scope is garbage collected. I only got the answers about prototype scope garbage collection, but the articles regarding singleton scope were not clear to me. Could someone give the details on this issue.
问题:
回答1:
In Spring, most of the classes you write will be Singletons. This means that there is only ever one instance of these classes created. These classes are created when the Spring container starts and are destroyed when the Spring container stops.
The reason that Spring singleton objects are different from simple Java objects, is that the container maintains a reference to them, and they are able to be used anywhere in your code at any time.
I'll give you an example using the Spring container to illustrate what I mean. This is NOT how you should do this normally when writing a Spring app, this is just an example.
@Component
public class ExampleClass implements ApplicationContextAware {
/*
* The ApplicationContextAware interface is a special interface that allows
* a class to hook into Spring's Application Context. It should not be used all
* over the place, because Spring provides better ways to get at your beans
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
MyBean bean = applicationContext.getBean("MyBean");
}
}
What the above code does is say to Spring "I want the instance of MyBean that you have discovered when the container started" (Classpath Scanning). Spring should have a (proxy) instance of this class already created and available for your use.
From the Spring Documentation
The Spring IoC container creates exactly one instance of the object defined by that bean definition. This single instance is stored in a cache of such singleton beans, and all subsequent requests and references for that named bean return the cached object.
Because that bean has been cached inside the application context, it is never eligible for garbage collection until the application context is destroyed.
回答2:
This doesn't seem to be entirely true. We have an enterprise spring application with close to 12000 singlton classes. If the JVM regardless of the application server, is started with around 4GBs of heap the heap fills up in around 3 redeploys or even undeploy and deploy. Even without any activity other then the deployment. The heap dump too, shows exactly 3 copies of the singletons. So it's not actually getting destroyed with application context. We have looked for a solution to this without success as this is a big time waster for the developers. They have to waste a lot of time recycling application server often while debugging or testing. In case of weblogic this happens even when just stopping and starting the application a few times.