I've got code that I am using from another team and I have spent days trying to track down a suspected memory leak in my application. I get an OutOfMemory error after a few redploys. I have used several tools to track down the leak including YourKit Java Profiler and IBM's Support Assisant Memory Analyzer. My app is a Spring 3.0.5 J2EE app running on WebSphere 6.1 using spring-mvc annotation driven controllers.
Most of the research I have done points to a class I find very suspect, we'll call it MyFactory and it looks like this:
import org.springframework.context.ApplicationContextAware;
public final class MyFactory implements ApplicationContextAware {
//this should be changed to be non static after getInstance is removed
private static ApplicationContext applicationContext;
public MyFactory() {
//empty
}
public static SettingObjectFactory getInstance() {
return (MyFactory) applicationContext.getBean("MyFactory");
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
MyFactory.applicationContext = applicationContext;
}
}
There is a whole bunch of other logic in this class that I left out that basically reads data from a database and stores it in memory (near cache). However, this class seems to hang on to the ApplicationContext after the application has been redployed.
Is this class's classloader hanging onto the ApplicationContext or preventing it from being completely cleaned up? I know that we don't need the getInstance method anymore, and I don't see a need for making this class have a static ApplicationContext - it seems to me Spring should enforce the singleton-ness of this class.
So static classes and associated static variables will never be garbage collected. Thus, using too many static variables leads to memory leaks.
Holding the references of the object and resources that are no longer needed is the main cause of the memory leaks in android applications. As it is known that the memory for the particular object is allocated within the heap and the object point to certain resources using some object reference.
Yes, holding a static reference to an ApplicationContext is liable to cause memory leaks in many setups. The way that some appservers and JVms interact with their classloading means that objects referenced in static fields can be retained within the PermGen memory pool (in the Sun Hotspot JVM, at least). Spring appcontexts can be very large object graphs, depending on what your context config looks like.
The only permanent solution to this that I've found is to avoid hot-deployment in production environments, which gets around the permgen recycling problem altogether. It's still annoying in a development environment, though.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With