Tengo un código que estoy usando de otro equipo y he pasado varios días intentando rastrear una posible pérdida de memoria en mi aplicación. Obtengo un error OutOfMemory después de algunos redploys. He utilizado varias herramientas para rastrear la fuga, incluido YourKit Java Profiler y IBM Assisant Memory Analyzer de IBM. Mi aplicación es una aplicación Spring 3.0.5 J2EE que se ejecuta en WebSphere 6.1 utilizando controladores accionados por anotación spring-mvc.¿Podría declarar un ApplicationContext estático causar una pérdida de memoria? (Spring 3)
mayor parte de la investigación que he hecho puntos a una clase me parece muy sospechoso, lo llamaremos MyFactory y se ve así:
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;
}
}
Hay un montón de otra lógica en esta clase que dejé de lado que básicamente lee datos de una base de datos y los almacena en la memoria (cerca de la caché). Sin embargo, esta clase parece aferrarse a ApplicationContext después de que la aplicación se haya redistribuido.
¿El cargador de clases de esta clase está colgando en ApplicationContext o impidiendo que se limpie por completo? Sé que ya no necesitamos el método getInstance, y no veo la necesidad de hacer que esta clase tenga un ApplicationContext estático; me parece que Spring debería hacer cumplir el singleton-ness de esta clase.
Gracias skaffman por confirmar mis sospechas. Lo REALMENTE extraño de este tema es que tenemos varias docenas de aplicaciones que usan este código, pero la aplicación en la que estoy trabajando parece ser la única que pierde memoria. La aplicación que gotea es la primera en usar Spring 3.0.5 (las aplicaciones anteriores estaban en 2.5.x). No puedo pensar en ninguna otra diferencia que haga que esta fuga aparezca ahora. ¿¿Algunas ideas?? –
@Ryan: depende en gran medida de lo que contenga el contexto. BeanPostProcessors, por ejemplo, no se ven explícitamente anulados por el contexto cuando se apaga, y se basa en la recolección de elementos no utilizados para poner en marcha. No todos los contextos los usarán. – skaffman