我有我正在使用的来自另一个团队的代码,我花了几天时间试图追踪我的应用程序中可疑的内存泄漏。几次 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/