usar new icon example codigo borderfactory java eclipse memory-management java-8

new - Java 8 asignando demasiada memoria



new icon java (2)

Estoy ejecutando Eclipse 4.3 con Java 7 JRE . Cuando actualizo a Java 8 JRE , Eclipse consume de repente más memoria. Si ejecuto Eclipse con JRE 7 directamente en mi área de trabajo, asigna 600 MB de RAM de acuerdo con el Administrador de tareas. Cuando uso JRE 8 , este valor es de 750 MB.

Peor aún, si ejecuto un programa Java grande que normalmente asigna aproximadamente 10 GB de RAM con JRE 7 , el cambio a JRE 8 hace que asigne 12 GB de RAM.

¿Alguien sabe qué causa esta asignación extra de RAM? He probado ajustes de diferentes opciones pero sin éxito:

-XX:ReservedCodeCacheSize= -XX:MaxMetaspaceSize= -XX:MetaspaceSize= ...


En la forma en que se formula la pregunta

por qué Java 8 asigna demasiada memoria en mi máquina

No creo que nadie pueda responder, sin embargo, hay varias pautas que pueden ayudar. Dado que está midiendo la memoria a través del administrador de tareas, le interesa el uso total de RSS. Asi que

  • Paso 1: compare los valores predeterminados de JVM entre la versión que está ejecutando. Puede obtenerlos usando java -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version command para ambos jdks. Al usar la ordenación de texto en la parte superior de la salida, podrá obtener una buena diferencia con cualquier herramienta de comparación. Cosas como cambiar el colector de GC predeterminado y el tamaño de la pila de hilos afectarán mucho al RSS final.
  • Paso 2: Mida la asignación para cada grupo de memoria. En general, la memoria total utilizada por Java se puede calcular utilizando heap + metasize + code cache + native + (thread_stack_size * maximum_number_of_threads)
    • La memoria de pila es fácilmente medible (¡y podría ser fácil de comparar!) Con herramientas maduras ( Eclipse Memory Analyzer , VisualVM , etc.). Si su memoria aumenta en el área de montón, tiene mucha suerte. En vm visual adicional, le permite instalar un complemento que mostrará los valores de todas las agrupaciones de memoria accesibles a través de jmx.
    • metasize (también conocido como permgen en jdk <8) debería ser más o menos igual y se podría encontrar con la herramienta jmap . No es necesario jugar con la bandera, puedes obtener el número y simplemente comparar cada vez que se aumenta o no.
    • Caché de código : además del caché de código reservado, puede establecer el caché de código inicial (y eso afectará la cantidad de RSS que se use).
    • nativo: es un poco de oveja negra. Si el resto de las agrupaciones de memoria son iguales (el aumento de memoria es de 2 GB), la pérdida de memoria debe estar en algún lugar del área nativa. La única herramienta que conozco es jcmd y tiene una extensa documentación en jcmd .

No técnico: aunque ajustar varias opciones para reducir la memoria puede ayudar, las posibilidades de obtener los valores correctos están cerca de encontrar la aguja en el pajar. Realmente recomendaría tener un acerca de cómo se usa RSS en Java. ¡Este conocimiento será útil durante bastantes años!

Por favor, avíseme cuando quiera más referencias concretas o una mejor explicación. Y ... buena suerte con tu búsqueda ;-)


Puedo confirmar que una aplicación web en la que estoy trabajando (Jetty, Struts2, JDBC) consume aproximadamente 300 MB más de RAM (1.2G) justo después del inicio cuando se ejecuta en JRE 1.8.0_72 en comparación con JRE 1.7.0_80. La aplicación se ejecuta en Centos 6 x64 y para hacer que la medición de la memoria sea lo más transparente posible. He inhabilitado el intercambio y establecido -Xms igual a -Xmx (40% de RAM disponible). He usado dstat --top-mem o top -m para obtener la memoria total consumida por el proceso java.

Además, cuando los clientes web se conectan con demasiada frecuencia a la aplicación, la memoria consumida total aumenta hasta que el sistema se queda sin memoria y mata el proceso java. Lo único que puedo ver es una información en / var / log / messages:

10 de noviembre 21:29:54 mi kernel: Falta memoria: proceso de matar 26610 (java) puntaje 570 o sacrificar a un niño

Cuando ejecuto un bucle infinito desde bash que invoca 4 clientes Web paralelos que se conectan a la aplicación (= establece una nueva conexión TCP), solicita el estado de la aplicación y desconecta, la memoria total consumida por la aplicación aumenta de 100 a 200 KB por minuto. Cada cliente hace 6-10 solicitudes por minuto. El tamaño de la memoria dinámica utilizada es estable.