声明静态ApplicationContext会导致内存泄漏吗? (春季3) [英] Could declaring a static ApplicationContext cause a memory leak ? (Spring 3)

查看:91
本文介绍了声明静态ApplicationContext会导致内存泄漏吗? (春季3)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经从另一个团队使用了我的代码,并且花了几天时间试图在我的应用程序中查找可疑的内存泄漏.经过几次重新部署后,我收到了OutOfMemory错误.我使用了多种工具来跟踪泄漏,包括YourKit Java Profiler和IBM的Support Assisant Memory Analyzer.我的应用程序是使用spring-mvc注释驱动的控制器在WebSphere 6.1上运行的Spring 3.0.5 J2EE应用程序.

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.

我所做的大部分研究都指向一个我非常怀疑的类,我们将其称为MyFactory,它看起来像这样:

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;
    }


}

在该类中,我遗漏了很多其他逻辑,它们基本上是从数据库中读取数据并将其存储在内存中(在高速缓存附近).但是,在重新部署应用程序之后,此类似乎仍挂在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.

此类的类加载器是挂在ApplicationContext上还是阻止其被彻底清除?我知道我们不再需要getInstance方法,并且我也不需要使此类具有静态ApplicationContext-在我看来Spring应该加强此类的单例性.

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.

推荐答案

是的,在许多设置中,持有对ApplicationContext的静态引用可能会导致内存泄漏.某些应用服务器和JVms与它们的类加载进行交互的方式意味着,可以将在静态字段中引用的对象保留在PermGen内存池中(至少在Sun Hotspot JVM中). Spring appcontexts可以是非常大的对象图,具体取决于您的上下文配置是什么.

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.

这篇关于声明静态ApplicationContext会导致内存泄漏吗? (春季3)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆