java - 声明静态 ApplicationContext 会导致内存泄漏吗? ( Spring 3)

标签 java spring memory-leaks websphere

我有我正在使用的来自另一个团队的代码,我花了几天时间试图追踪我的应用程序中可疑的内存泄漏。几次 redploy 后我收到 OutOfMemory 错误。我使用了多种工具来追踪泄漏,包括 YourKit Java Profiler 和 IBM 的 Support Assisant Memory Analyzer。我的应用程序是一个在 WebSphere 6.1 上运行的 Spring 3.0.5 J2EE 应用程序,使用 spring-mvc 注释驱动 Controller 。

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

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 上。

这个类的类加载器是否卡在 ApplicationContext 上或阻止它被完全清理?我知道我们不再需要 getInstance 方法,而且我认为没有必要让这个类有一个静态的 ApplicationContext - 在我看来 Spring 应该强制这个类的单例性。

最佳答案

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

我发现的唯一永久性解决方案是避免在生产环境中进行热部署,这完全解决了 permgen 回收问题。不过,它在开发环境中仍然很烦人。

关于java - 声明静态 ApplicationContext 会导致内存泄漏吗? ( Spring 3),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5853019/

相关文章:

java - 我如何在 spring mvc 中使用我的 Controller ?

java - 将任务提交到 ThreadPoolTask​​Executor 时出现 RejectedExecutionException

java - Hibernate 延迟加载字段

c++ - 带有 TTF 的 SDL 内存泄漏

Java-在构造函数中使用实例变量循环遍历数组

java - 找不到符号 InputStreamer

java - 使用不同的查询参数 JOIN 不同的方法 : REST

c++ - 在 Windows 上诊断构成 R 包一部分的 C++ 代码中的内存泄漏

c - 释放调用者中由被调用者重新分配的内存?

java - 开始 : Applet not initialized error in NetBeans IDE 8. 0