tutorial mvc framework español ejemplos edicion cuarta books arquitectura accion java memory-management jvm

mvc - ¿Por qué la gestión de memoria es tan visible en Java VM?



spring java tutorial (5)

El título de su pregunta es engañoso (no a propósito, lo sé): problemas con PermSize (y hay muchos de ellos, fui uno de los primeros en diagnosticar un problema de Tomcat / Sun PermGen hace años, cuando no existía) cualquier conocimiento sobre el tema todavía no es una especificidad de Java sino una especificación de VM de Sun.

Si usa una máquina virtual que no usa la generación permanente (como, por ejemplo, una máquina virtual de IBM, si no me equivoco), no puede tener problemas con el permgen.

Por lo tanto, no es un problema de "Java", sino un problema de implementación de Sun VM.

Estoy jugando y escribiendo algunas aplicaciones web simples basadas en Spring y desplegándolas en Tomcat. Casi de inmediato, me encuentro con la necesidad de personalizar la configuración de JVM de Tomcat con -XX: MaxPermSize (y -Xmx y -Xms); sin esto, el servidor se queda fácilmente sin espacio PermGen.

¿Por qué este es un problema para las máquinas virtuales de Java en comparación con otros lenguajes recolectados en la basura? La comparación de los recuentos del "uso de la memoria de sintonía X" para X en Java, Ruby, Perl y Python, muestra que Java tiene fácilmente un orden de magnitud más de aciertos en Google que los otros idiomas combinados.

También estaría interesado en referencias a documentos técnicos / publicaciones de blog / etc. que expliquen las opciones de diseño detrás de las implementaciones de JVM GC, en diferentes JVM o en comparación con otras máquinas virtuales de lenguaje interpretado (por ejemplo, comparando Sun o IBM JVM con Parrot ). ¿Hay razones técnicas por las que los usuarios de JVM todavía tienen que lidiar con tamaños de pila / permgen que no se ajustan automáticamente?


Esto se debe a que Tomcat se ejecuta en la máquina virtual de Java, mientras que otros lenguajes se compilan o interpretan y se ejecutan en su máquina real. Cuando configuras -Xmx y -Xms estás diciendo que quieres que JVM se ejecute como una computadora con una cantidad de RAM en algún lugar dentro del rango establecido.

Creo que la razón por la que tantas personas se encuentran con esto es que los valores predeterminados son relativamente bajos y las personas terminan alcanzando el techo predeterminado muy rápidamente (en lugar de esperar hasta que se quede sin RAM como lo haría con otros idiomas).


Java te da un poco más de control sobre la memoria: marca uno para las personas que desean aplicar ese control allí, contra Ruby, Perl y Python, lo que te da menos control sobre eso. La implementación típica de Java también tiene mucha memoria (porque tiene un enfoque de recolección de basura más avanzado) contra las implementaciones típicas de los lenguajes dinámicos ... pero si miras a JRuby o Jython, encontrarás que no es un problema de lenguaje (cuando estos diferentes idiomas usan la misma máquina virtual subyacente, los problemas de memoria están prácticamente igualados). No conozco una implementación generalizada de "Perl en JVM", pero si hay una que estoy dispuesta a apostar, no sería muy diferente en términos de huella de JRuby o Jython.


La esencia de las respuestas de @WizardOfOdds y @ Alex-Martelli parece ser correcta: Java tiene un conjunto avanzado de opciones de GC, y algunas veces es necesario ajustarlas. Sin embargo, todavía no estoy del todo claro por qué podría diseñar una JVM con o sin una generación permanente. He encontrado un montón de enlaces útiles sobre la recolección de basura en Java, aunque no necesariamente en comparación con otros idiomas con GC. Brevemente:

Feliz de actualizar esta respuesta con más detalles si alguien los tiene.


Python / Perl / Ruby asignan su memoria con malloc () o una optimización de los mismos. El límite del espacio de almacenamiento dinámico lo determina el sistema operativo en lugar de la máquina virtual, por lo que no hay necesidad de opciones como -Xmxn. Además, la recolección de basura es más simple, basada principalmente en el conteo de referencias. Así que hay mucho menos para afinar.

Además, los lenguajes dinámicos tienden a implementarse con intérpretes de códigos de bytes en lugar de compiladores JIT, por lo que no se utilizan para el código crítico para el rendimiento de todos modos.