Could declaring a static ApplicationContext cause

2019-06-20 06:29发布

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.

1条回答
Emotional °昔
2楼-- · 2019-06-20 06:58

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.

查看更多
登录 后发表回答