Rya*_*son 6 java websphere spring memory-leaks
我有来自另一个团队的代码,我花了几天时间试图追踪我的应用程序中可疑的内存泄漏.几次重新部署后,我得到一个OutOfMemory错误.我使用了几种工具来追踪泄漏,包括YourKit Java Profiler和IBM的Support Assisant Memory Analyzer.我的应用程序是使用spring-mvc注释驱动的控制器在WebSphere 6.1上运行的Spring 3.0.5 J2EE应用程序.
我所做的大部分研究都指向了一个我觉得非常怀疑的课程,我们称之为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;
}
}
Run Code Online (Sandbox Code Playgroud)
我遗漏了这个类中的一大堆其他逻辑,基本上从数据库中读取数据并将其存储在内存中(靠近缓存).但是,在重新部署应用程序之后,此类似乎会挂起到ApplicationContext.
这个类的类加载器是否挂在ApplicationContext上或阻止它被彻底清除?我知道我们不再需要getInstance方法,而且我认为不需要让这个类有一个静态的ApplicationContext - 在我看来Spring应该强制执行这个类的单例.
是的,持有对ApplicationContext的静态引用很可能导致许多设置中的内存泄漏.某些appservers和JVms与其类加载交互的方式意味着静态字段中引用的对象可以保留在PermGen内存池中(至少在Sun Hotspot JVM中).Spring appcontexts可以是非常大的对象图,具体取决于您的上下文配置的外观.
我发现的唯一永久解决方案是避免在生产环境中进行热部署,这完全解决了permgen回收问题.不过,它在开发环境中仍然很烦人.
| 归档时间: |
|
| 查看次数: |
2494 次 |
| 最近记录: |