Parámetros de montón de JVM

Después de leer la pregunta ya realizada sobre el tema y de buscar en Google, aún no puedo tener una visión clara de la opción -Xms

Mi pregunta es: ¿cuál es la diferencia entre java -Xms=512m -Xmx=512m y java -Xms=64m -Xmx=512m ?

Por ahora tengo la siguiente respuesta:

La única diferencia está en la cantidad de recolecciones de basura que se ejecutarán durante la ejecución de mi aplicación y el número de asignaciones de memoria. ¿Estoy en lo cierto?

Aquí están mis razones para esta respuesta:

Establecer la opción -Xms en 512m no da como resultado que mi aplicación use realmente 512M de memoria física después del inicio. Supongo que esto está relacionado con la administración moderna de la memoria virtual del sistema operativo y las asignaciones de páginas diferidas. (Noté que establecer -Xms a 512M o a 64M no cambia para nada la memoria usada inicial que se informa ya sea por arriba en Linux o por el administrador de tareas en Windows)

¿Alguien puede ayudarme a comprender el impacto de esta opción de Xms o dirigirme a enlaces que me ayudarán a entenderlo?

Gracias por adelantado

Manu

Para resumir la información encontrada después del enlace: La JVM asigna la cantidad especificada por -Xms, pero el sistema operativo generalmente no asigna páginas reales hasta que se necesiten. Por lo tanto, la JVM asigna la memoria virtual según lo especificado por Xms, pero solo asigna la memoria física que se necesita.

Puede ver esto usando Process Explorer por Sysinternals en lugar de administrador de tareas en Windows.

Entonces, hay una diferencia real entre usar -Xms64M y -Xms512M. Pero creo que la diferencia más importante es la que ya ha señalado: el recolector de basura se ejecutará con más frecuencia si realmente necesita los 512MB pero solo comenzó con 64MB.

La JVM comenzará con el uso de la memoria en el nivel de stack inicial. Si el maxheap es más alto, crecerá al tamaño máximo de mapeo ya que los requisitos de memoria exceden su memoria actual.

Asi que,

  • -Xms512m -Xmx512m

JVM comienza con 512 M, nunca cambia el tamaño.

  • -Xms64m -Xmx512m

JVM comienza con 64M, crece (hasta techo máximo de 512) si mem. los requisitos exceden 64.

Además de los parámetros de Heap estándar -Xms y -Xmx , también es bueno saber -XX:PermSize y -XX:MaxPermSize , que se usa para especificar el tamaño del espacio Perm Gen porque, aunque podría tener espacio en otra generación en el montón, puede ejecutar sin memoria si su espacio de memoria permanente se llena. Este enlace también tiene una buena visión general de algunos parámetros importantes de JVM .

La JVM redimensiona el montón de forma adaptativa, lo que significa que intentará encontrar el mejor tamaño de almacenamiento dynamic para su aplicación. -Xms y -Xmx simplemente especifican el rango en el que la JVM puede operar y cambiar el tamaño del montón. Si -Xms y -Xmx tienen el mismo valor, el tamaño del almacenamiento dynamic de la JVM se mantendrá constante en ese valor.

Por lo general, lo mejor es establecer -Xmx y dejar que la JVM encuentre el mejor tamaño de almacenamiento dynamic, a menos que haya una razón específica por la que necesite darle a la JVM un gran montón en el lanzamiento de JVM.

En cuanto a cuando la JVM realmente solicita la memoria del sistema operativo, creo que depende de la plataforma y la implementación de la JVM. Imagino que no solicitaría la memoria hasta que tu aplicación realmente la necesite. -Xmx y -Xms solo reserva la memoria.

si escribió: -Xms512m -Xmx512m cuando comienza, java asigna en esos momentos 512m de RAM para su proceso y no puede incrementarse.

-Xms64m -Xmx512m cuando se inicia, java asigna solo 64m de ram para su proceso, pero java puede incrementar su ocupación de memoria a 512m.

Creo que lo segundo es mejor porque le das a java la gestión automática de la memoria.

my_file.scala este ejemplo de juguete en scala , my_file.scala :

 object MyObject { def main(args: Array[String]) { var ab = ArrayBuffer.empty[Int] for (i <- 0 to 100 * 1000 * 1000) { ab += i if (i % 10000 == 0) { println("On : %s".format(i)) } } } } 

Lo ejecuté con:

 scala -J-Xms500m -J-Xmx7g my_file.scala 

y

 scala -J-Xms7g -J-Xmx7g my_file.scala 

Sin duda hay pausas notables en la versión de -Xms500m . Estoy seguro de que las pausas cortas son carreras de recolección de basura, y las largas son asignaciones de stack.