¿Cómo se determina el tamaño de almacenamiento dinámico máximo de Java predeterminado?

421

Si omito la -Xmxnopción de la línea de comandos de Java, se utilizará un valor predeterminado. De acuerdo con la documentación de Java

"el valor predeterminado se elige en tiempo de ejecución en función de la configuración del sistema"

¿Qué ajustes de configuración del sistema influyen en el valor predeterminado?

Richard Dorman
fuente
1
configuración del sistema significa: a) cliente jvm vs servidor jvm b) 32bit vs 64bit. Enlaces: 1) actualización de J2SE5.0 docs.oracle.com/javase/6/docs/technotes/guides/vm/… 2) breve respuesta: docs.oracle.com/javase/8/docs/technotes/guides/vm / gctuning /… 3) respuesta detallada: docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/… 4) cliente vs servidor: javacodegeeks.com/2011/07/jvm-options-client- vs-server.html
Vyshnav Ramesh Thrissur
2
Es difícil de entender por los enlaces anteriores. Resumiéndolas aquí: el tamaño de almacenamiento dinámico máximo para el Cliente jvm es de 256 mb (hay una excepción, lea los enlaces anteriores). El tamaño máximo de almacenamiento dinámico para el servidor jvm de 32 bits es de 1 gb y de 64 bits es de 32 gb (de nuevo, también hay excepciones aquí. Por favor, lea eso de los enlaces). Entonces es 256mb o 1gb o
32gb
Ver también stackoverflow.com/a/56036202/32453
rogerdpack

Respuestas:

507

En Windows, puede usar el siguiente comando para averiguar los valores predeterminados en el sistema donde se ejecutan sus aplicaciones.

java -XX: + PrintFlagsFinal -version | findtr HeapSize

Busque las opciones MaxHeapSize(para -Xmx) y InitialHeapSizepara -Xms.

En un sistema Unix / Linux, puedes hacer

java -XX: + PrintFlagsFinal -version | grep HeapSize

Creo que la salida resultante está en bytes.

piedras333
fuente
3
Esperaba una buena opción como esta, pero no funcionó para mí usando Java 6 VM de IBM.
Matt Lavin
¡Excelente! ¿Puedo jugar con todas estas opciones predeterminadas? ¿Cuál es la variable ENV correspondiente para cada uno?
Elist
28
En mi caso en Linux, InitialHeapSize = 262803264y MaxHeapSize = 4206886912que es de aproximadamente 256 MB y 4 GB si no me equivoco. ¿Esto significa que cada JVM comienza como si se iniciara con -Xms256m -Xmx4gopciones?
Yuriy Nakonechnyy
99
En un sistema Windows:java -XX:+PrintFlagsFinal -version | findstr /R /C:"HeapSize"
sp00m
1
@matanster En mi Linux -versionsuprime el texto largo de "uso" stderr.
Franklin Yu
115

Para Java SE 5: según la recolección de basura Ergonomía [Oracle] :

tamaño inicial del montón:

Mayor de 1/64 de la memoria física de la máquina en la máquina o algún mínimo razonable. Antes de J2SE 5.0, el tamaño de almacenamiento dinámico inicial predeterminado era un mínimo razonable, que varía según la plataforma. Puede anular este valor predeterminado utilizando la opción de línea de comandos -Xms.

tamaño máximo de almacenamiento dinámico:

Menor de 1/4 de la memoria física o 1 GB. Antes de J2SE 5.0, el tamaño de almacenamiento dinámico máximo predeterminado era 64 MB. Puede anular este valor predeterminado utilizando la opción de línea de comandos -Xmx.

ACTUALIZAR:

Como señaló Tom Anderson en su comentario, lo anterior es para máquinas de clase de servidor. De Ergonomía en la máquina virtual 5.0 JavaTM :

En la versión 5.0 de la plataforma J2SE, una clase de máquina denominada máquina de clase servidor se ha definido como una máquina con

  • 2 o más procesadores físicos
  • 2 o más Gbytes de memoria física

con la excepción de las plataformas de 32 bits que ejecutan una versión del sistema operativo Windows. En todas las demás plataformas, los valores predeterminados son los mismos que los valores predeterminados para la versión 1.4.2.

En la plataforma J2SE versión 1.4.2 por defecto, se hicieron las siguientes selecciones

  • tamaño de almacenamiento dinámico inicial de 4 Mbyte
  • tamaño de almacenamiento dinámico máximo de 64 Mbyte
dogbane
fuente
44
Advertencia: eso es para máquinas de clase de servidor, no de clase de cliente. Debe leer ese documento junto con java.sun.com/docs/hotspot/gc5.0/ergo5.html que define esos términos y lo que sucede con las máquinas de clase cliente. dogbane, ¿podría sugerir humildemente que edite su respuesta para citar los pasajes relevantes?
Tom Anderson el
3
Ese es un valor predeterminado ridículamente bajo en 2012. Muy pocas aplicaciones serias caben dentro de 64 megabytes.
Mark E. Haase
1
Consulte la respuesta de Ernesto del 30 de octubre de 2012 para máquinas cliente después de la actualización 18 de Java 6.
Andy Thomas
También tenga en cuenta que dice: "Los límites y las fracciones dados para el tamaño de almacenamiento dinámico son correctos para J2SE 5.0. Es probable que sean diferentes en versiones posteriores a medida que las computadoras se vuelven más potentes".
Lodovik
Por cierto, este algo es solo para Parallel Garbage Collector.
Mike Argyriou
45

Java 8 lleva más de 1 / 64º de la memoria física para su xmssize (TamañoPila mínimo) y menos de 1 / cuarto de la memoria física para su -Xmxsize (Máximo TamañoPila).

Puede verificar el tamaño predeterminado del almacenamiento dinámico Java mediante:

En Windows :

java -XX:+PrintFlagsFinal -version | findstr /i "HeapSize PermSize ThreadStackSize"

En Linux :

java -XX:+PrintFlagsFinal -version | grep -iE 'HeapSize|PermSize|ThreadStackSize'

¿Qué ajustes de configuración del sistema influyen en el valor predeterminado?

La memoria física de la máquina y la versión Java.

Sarat Chandra
fuente
55
¿No es 1/64 en lugar de 1/6?
Vyshnav Ramesh Thrissur
1
Sí, Xmssize (tamaño mínimo de pila / tamaño inicial inicial) es más de 1/64 de su memoria física y Xmxsize (tamaño máximo de pila / tamaño máximo de pila) es menos de 1/4 de su memoria física. (Por ejemplo, para mi Mac, con 16 GB de RAM, obtengo uintx InitialHeapSize: = 268435456 {product} uintx MaxHeapSize: = 4294967296 {product}, i, e Xms es 268 MB y Xmx es 4.29 GB
sjethvani
1
Por favor edite la respuesta. Es 1/64, no 1/6.
emeraldhieu
35

Esto se cambió en la actualización 18 de Java 6 .

Suponiendo que tenemos más de 1 GB de memoria física (bastante común en estos días), siempre es 1/4 de su memoria física para el servidor vm.

ernesto
fuente
8
Incorrecto, dice la página vinculadagreater than or equal to 1 gigabyte of physical memory results in a maximum heap size of 256 megabytes
Paolo Fulgoni
55
Acabo de comprobar en una máquina Linux con 5 GB de memoria física. El almacenamiento dinámico máximo predeterminado se muestra como 1.5 gb
ernesto
1
@PaoloFulgoni no, otro ejemplo práctico que observo en este momento: 129 Gbytes de memoria física da como resultado 32 Gbytes de tamaño máximo de almacenamiento dinámico
Kirill
Consulte la respuesta de apl para saber por qué esto es correcto: stackoverflow.com/a/13310792/32453 Consulte también stackoverflow.com/a/56036202/32453
rogerdpack
16

Ernesto tiene razón. Según el enlace que publicó [1]:

Actualización de la configuración del montón de JVM del cliente

En la JVM del cliente ...

  • El tamaño de almacenamiento dinámico máximo predeterminado es la mitad de la memoria física hasta un tamaño de memoria física de 192 megabytes y, de lo contrario, un cuarto de la memoria física hasta un tamaño de memoria física de 1 gigabyte.

    Por ejemplo, si su máquina tiene 128 megabytes de memoria física, el tamaño máximo de almacenamiento dinámico es 64 megabytes, y una memoria física mayor o igual a 1 gigabyte da como resultado un tamaño de almacenamiento dinámico máximo de 256 megabytes.

  • JVM no utiliza el tamaño máximo de almacenamiento dinámico a menos que su programa cree suficientes objetos para requerirlo. Se asigna una cantidad mucho menor, denominada tamaño de almacenamiento dinámico inicial, durante la inicialización de JVM. ...

  • ...
  • La ergonomía de la configuración del montón JVM del servidor ahora es la misma que la del Cliente, excepto que el tamaño máximo predeterminado del montón para JVM de 32 bits es 1 gigabyte , que corresponde a un tamaño de memoria física de 4 gigabytes, y para JVM de 64 bits es 32 gigabytes , correspondiente a un tamaño de memoria física de 128 gigabytes.

[1] http://www.oracle.com/technetwork/java/javase/6u18-142093.html

apl
fuente
8

¡Finalmente!

A partir de Java 8u191 ahora tiene las opciones:

-XX:InitialRAMPercentage
-XX:MaxRAMPercentage
-XX:MinRAMPercentage

que se puede usar para dimensionar el montón como un porcentaje de la RAM física utilizable. (que es lo mismo que la RAM instalada menos lo que usa el núcleo).

Consulte las Notas de la versión de Java8 u191 para obtener más información. Tenga en cuenta que las opciones se mencionan bajo un encabezado de Docker, pero de hecho se aplican si se encuentra en el entorno de Docker o en un entorno tradicional.

El valor predeterminado para MaxRAMPercentagees 25%. Esto es extremadamente conservador.

Mi propia regla: si su host está más o menos dedicado a ejecutar la aplicación java dada, entonces puede aumentar drásticamente sin problemas. Si está en Linux, solo ejecuta daemons estándar y ha instalado RAM desde alrededor de 1 Gb o más, entonces no dudaría en usar el 75% para el montón de JVM. Nuevamente, recuerde que este es el 75% de la RAM disponible , no la RAM instalada . Lo que queda son los otros procesos de aterrizaje de usuario que pueden ejecutarse en el host y los otros tipos de memoria que necesita la JVM (por ejemplo, para la pila). En conjunto, esto generalmente encajará bien en el 25% que queda. Obviamente, con aún más RAM instalada, el 75% es una apuesta cada vez más segura. (Me gustaría que la gente de JDK hubiera implementado una opción en la que podría especificar una escalera)

Establecer la MaxRAMPercentageopción se ve así:

java -XX:MaxRAMPercentage=75.0  ....

Tenga en cuenta que estos valores porcentuales son de tipo 'doble' y, por lo tanto, debe especificarlos con un punto decimal. Obtiene un error un tanto extraño si usa "75" en lugar de "75.0".

Peter
fuente
7

el valor predeterminado se elige en tiempo de ejecución en función de la configuración del sistema

Echa un vistazo a la página de documentación .

Tamaño de montón predeterminado

A menos que los tamaños de almacenamiento dinámico iniciales y máximos se especifiquen en la línea de comandos, se calculan en función de la cantidad de memoria en la máquina.

  1. Tamaños predeterminados iniciales y máximos de almacenamiento dinámico de JVM del cliente:

    El tamaño de almacenamiento dinámico máximo predeterminado es la mitad de la memoria física hasta un tamaño de memoria física de 192 megabytes (MB) y, de lo contrario, un cuarto de la memoria física hasta un tamaño de memoria física de 1 gigabyte (GB) .

  2. Tamaños predeterminados iniciales y máximos de almacenamiento dinámico de JVM del servidor:

    En las JVM de 32 bits, el tamaño de almacenamiento dinámico máximo predeterminado puede ser de hasta 1 GB si hay 4 GB o más de memoria física . En JVM de 64 bits, el tamaño de almacenamiento dinámico máximo predeterminado puede ser de hasta 32 GB si hay 128 GB o más de memoria física

¿Qué ajustes de configuración del sistema influyen en el valor predeterminado?

Puede especificar los tamaños de almacenamiento dinámico inicial y máximo utilizando los indicadores -Xms (tamaño de almacenamiento dinámico inicial) y -Xmx (tamaño de almacenamiento dinámico máximo). Si sabe cuánto montón necesita su aplicación para funcionar bien, puede establecer -Xms y -Xmx en el mismo valor

Ravindra babu
fuente
5

El Xmsy Xmxson bandera de la máquina virtual Java (JVM):

  • Xms: initial and minimumJVMheap size
    • Format: -Xmx<size>[g|G|m|M|k|K]
    • Default Size:
      • -server modo: 25% de memoria física libre,> = 8 MB y <= 64 MB
      • -client mode: 25% de memoria física libre,> = 8 MB y <= 16 MB
    • Typical Size:
      • -Xms128M
      • -Xms256M
      • -Xms512M
    • Function/ Effect:
      • -> JVM comienza con asignación de Xmsmemoria de tamaño
  • Xmx: maximumJVMheap size
    • Format: -Xmx<size>[g|G|m|M|k|K]
    • Default Size:
      • <= R27.2
        • Windows: 75%de memoria física total hasta1GB
        • Linux/Solaris: 50%de memoria física disponible hasta1GB
      • >= R27.3
        • Windows X64: 75%de memoria física total hasta2GB
        • Linux/Solaris X64: 50%de memoria física disponible hasta2GB
        • Windows x86: 75%de memoria física total hasta1GB
        • Linux/Solaris X86: 50%de memoria física disponible hasta1GB
    • Typical Size:
      • -Xmx1g
      • -Xmx2084M
      • -Xmx4g
      • -Xmx6g
      • -Xmx8g
    • Function/ Effect:
      • -> JVM permite usar memoria de Xmxtamaño máximo
        • cuando exceda Xmx, voluntadjava.lang.OutOfMemoryError
          • ¿Cómo arreglarlo OutOfMemoryError?
            • exceder el Xmxvalor
              • por ejemplo: de -Xmx4ga-Xmx8g

Mas detalle

ver documento oficial: -X Opciones de línea de comandos

crifan
fuente
¿No es eso para el JRockit JVM? (a diferencia de JVM Hotspot de Oracle)
Peter
4

Varios parámetros afectan el tamaño de la generación. El siguiente diagrama ilustra la diferencia entre el espacio comprometido y el espacio virtual en el montón. En la inicialización de la máquina virtual, se reserva todo el espacio para el montón. El tamaño del espacio reservado se puede especificar con la -Xmxopción Si el valor del -Xmsparámetro es menor que el valor del -Xmxparámetro, no todo el espacio reservado se compromete inmediatamente en la máquina virtual. El espacio no comprometido se etiqueta como "virtual" en esta figura. Las diferentes partes del montón (generación permanente, generación permanente y generación joven) pueden crecer hasta el límite del espacio virtual según sea necesario.

ingrese la descripción de la imagen aquí

De manera predeterminada, la máquina virtual aumenta o reduce el montón en cada colección para tratar de mantener la proporción de espacio libre para los objetos vivos en cada colección dentro de un rango específico. Este rango objetivo se establece como un porcentaje por los parámetros - XX:MinHeapFreeRatio=<minimum>y -XX:MaxHeapFreeRatio=<maximum>, y el tamaño total está limitado por debajo -Xms<min>y por arriba por -Xmx<max>.

Parámetro Valor predeterminado

MinHeapFreeRatio 40

MaxHeapFreeRatio 70

-Xms 3670k

-Xmx 64m

Los valores predeterminados de los parámetros de tamaño de almacenamiento dinámico en sistemas de 64 bits se han ampliado en aproximadamente un 30%. Este aumento está destinado a compensar el mayor tamaño de los objetos en un sistema de 64 bits.

Con estos parámetros, si el porcentaje de espacio libre en una generación cae por debajo del 40%, la generación se expandirá para mantener el 40% de espacio libre, hasta el tamaño máximo permitido de la generación. Del mismo modo, si el espacio libre supera el 70%, la generación se contratará de modo que solo el 70% del espacio sea libre, sujeto al tamaño mínimo de la generación.

Las aplicaciones de servidores grandes a menudo experimentan dos problemas con estos valores predeterminados. Uno es el inicio lento, porque el montón inicial es pequeño y debe redimensionarse en muchas colecciones importantes. Un problema más acuciante es que el tamaño de almacenamiento dinámico máximo predeterminado es irracionalmente pequeño para la mayoría de las aplicaciones de servidor. Las reglas generales para las aplicaciones de servidor son:

  • A menos que tenga problemas con las pausas, intente otorgar tanta memoria como sea posible a la máquina virtual. El tamaño predeterminado (64 MB) suele ser demasiado pequeño.
  • Establecer -Xms y -Xmx en el mismo valor aumenta la previsibilidad al eliminar la decisión de tamaño más importante de la máquina virtual. Sin embargo, la máquina virtual no puede compensar si realiza una mala elección.
  • En general, aumente la memoria a medida que aumenta el número de procesadores, ya que la asignación puede ser paralela.

    Ahí está el artículo completo.

theodor
fuente