Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cleanly destroy Spring Application Context

I have been running in to problems making sure that a spring application context that i am destroying has completely gone away, and cant see the object being garbage collected. When i look at the instance in VisualVM i can see that there are a number of outstanding references to both the context and it's bean factory that remain once the context is closed and destroyed. These all to be in relation to the initial set up of the bean factory (during the refresh method of AbstractApplicationContext) which registers the bean factory and the context with various bean post processors etc.

There do not appear to be any methods on the bean factory or on the application contexts (even the refreshable ones) that do more than remove the lowest level reference to the bean factory. The result is that it appears to be leaking memory, and in certain circumstances preventing the clean re-creation of a context.

I am asking as the software i am working on at the moment may dynamically create / destroy and then re-create the context (as modules are dynamically loaded and unloaded) and the leftover elements of the context and bean factory are causing problems with components such as spring-data-jpa (especially the proxy that binds the repository interfaces to the repository implementations).

Does anyone know of a way whereby i can cleanly and completely remove a context and bean factory without having to completely close down the VM that initially created it?

like image 487
Mike Avatar asked Nov 02 '16 15:11

Mike


People also ask

What is the preferred way to close an application context?

When the web container will want to stop the application, the ContextLoadListener will receive the event from the servlet. And then based on this event it will close the application context. After the undeploy of application, the @PreDestroy method will be called and the application context will be closed.

How do you gracefully shutdown a spring boot application?

Use the static exit() method in the SpringApplication class for closing your spring boot application gracefully.

How do you close a spring context?

If we want to close the current context, one solution is to simply call the actuator /shutdown endpoint. Here, we've added a controller that implements the ApplicationContextAware interface and overrides the setter method to obtain the current application context.

Why do we need to close application context?

It is important to close the context properly because different lifecycle methods must have the chance to run. Consequently, the application can release the resources and do some clean-up.


1 Answers

Having looked into this again recently, i noticed that i was overriding the doClose() method of the context to make sure beans were completely destroyed, but was not calling the super.doClose() method, which meant that LiveBeansView.unregisterApplicationContext() / destroyBeans() / getLifecycleProcessor().onClose() and closeBeanFactory() were not being called.

I added this in, and (most) if not all contexts are now cleanly destroyed and garbage collected. I will assume that any outstanding contexts that are not destroyed are more probably issues in our own code with dangling references.

like image 80
Mike Avatar answered Sep 29 '22 04:09

Mike