ventas una registro registra notas nota libros libro las electronicos diario declaran credito contables como anotacion java spring jvm spring-annotations

java - una - configuración basada en la anotación de primavera: ¿el consumo de memoria es demasiado alto?



las notas de credito se declaran (2)

La forma en que construyes tu AnnotationConfigApplicationContext (que proporciona un paquete base de tus clases anotadas) requiere un escaneo classpath, por lo tanto, no es de extrañar que lleve tiempo y memoria.

Si desea evitar el análisis de classpath, puede intentar proporcionar el conjunto exacto de clases anotadas ( @Component s y @Configuration s) en su lugar, utilizando el constuctor correspondiente de AnnotationConfigApplicationContext .

Cuando noté un gran uso de RAM en mi aplicación cliente (basada en Swing), comencé a investigar y parece que de alguna manera está relacionado con la configuración basada en Annotation en Spring. Como verá en mis ediciones a continuación, me di cuenta de que esto ocurre solo en JVM de 64 bits.

Vea el siguiente código de prueba:

configuración basada en xml

<beans ....> <bean id="xmlConfigTest" class="at.test.XmlConfigTest" /> </beans> public class XmlConfigTest extends JFrame { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("config/applicationContext.xml"); XmlConfigTest frame = (XmlConfigTest) ctx.getBean("xmlConfigTest"); frame.setDefaultCloseOperation(EXIT_ON_CLOSE); frame.setVisible(true); } }

Utiliza hasta 32 MB de memoria, lo que me parece bien.

Ahora lo mismo con la configuración basada en anotaciones :

@Service public class AnnotationConfigTestFrame extends JFrame { public static void main(String[] args) throws InterruptedException { ApplicationContext ctx = new AnnotationConfigApplicationContext("at.test"); AnnotationConfigTestFrame frame = (AnnotationConfigTestFrame) ctx .getBean("annotationConfigTestFrame"); frame.setDefaultCloseOperation(EXIT_ON_CLOSE); frame.setVisible(true); } }

No solo se nota más tiempo para abrir el marco, sino que el consumo de memoria se dispara a 160MB de memoria al arrancar y luego se nivela a unos 152MB, lo cual me parece muy importante. Y recuerde, este es solo el caso más básico, la aplicación cliente i develope atm consume más de 400 MB, lo que es demasiado para máquinas antiguas.

¿Alguien tiene una explicación para este comportamiento? No entiendo..

(Usando 3.1.1.RELEASE aquí por cierto)

editar * Como sugiere axtavt, también intenté construir el AnnotationConfigApplicationContext directamente con Test-Class como argumento, por lo que no es necesario ningún classpath-scan. No cambió nada sobre el consumo de memoria, lamentablemente.

editar 2 eliminado, ver edición 3

edit 3 Ahora probé en la misma máquina (Windows 7 de 64 bits) con JVM de 32 y 64 bits y los programas de prueba desde arriba. Estos son los resultados:

configuración basada en xml:

32-Bit JVM: 16MB 64-Bit JVM: 31MB

configuración basada en la anotación:

32-Bit JVM: 17MB 64-Bit JVM: 160MB

Entonces, en JVM de 32 bits ambos programas están cerca, que es más o menos lo que esperaría. Sin embargo, en 64 bits, esto es diferente. Incluso el primer programa utiliza el doble de memoria en 64 bits, que ya parece ser demasiado. Todavía no es nada en contra del segundo programa, que usa casi 10 veces más memoria en 64 bits.

editar 4 Ahora probado bajo ubuntu también -> mismo efecto. Todavía no tengo idea de por qué está pasando esto. Esto es realmente un obstáculo para mí


Al inicio, se crean una gran cantidad de objetos java.lang.reflect.Method .

Estos objetos son elegibles para la recolección de basura, pero en el caso de su aplicación probablemente cause demasiadas colecciones de eden, lo que resulta en tiempos de inicio altos.

La mayoría de estos objetos java.lang.reflect.Method se asignan en el siguiente sitio:

Parece que se crean cuando Spring intenta encontrar setters en AnnotationConfigTestFrame que hereda muchos métodos de las super clases de java.awt y javax.swing . No leí atentamente el código relevante, pero como una prueba rápida para verificar esta hipótesis, hice lo siguiente:

@Service public class AnnotationConfigTestFrame /* extends JFrame */ { public static void main(String[] args) throws InterruptedException { ApplicationContext ctx = new AnnotationConfigApplicationContext(AnnotationConfigTestFrame.class); AnnotationConfigTestFrame frame = (AnnotationConfigTestFrame) ctx .getBean("annotationConfigTestFrame"); // frame.setDefaultCloseOperation(EXIT_ON_CLOSE); // frame.setVisible(true); waitABit(); printRuntimeStats(); System.exit(0); } }

es decir, que AnnotationConfigTestFrame no hereda de javax.swing.JFrame . ¡Ahora el uso de la memoria para buscar el frijol es razonablemente bajo!

Esto podría darte pistas para depurar esto más.