Pregunta

Dados estos dos comandos

A:

$ java -Xms10G -Xmx10G myjavacode input.txt

B:

$ java -Xms5G -Xmx5G myjavacode input.txt

Tengo dos preguntas:

  1. Dado que el comando A reserva más memoria con sus parámetros, ¿A correrá más rápido que B?
  2. ¿Cómo -Xmx y -Xms afectan el proceso de ejecución y la salida de mi programa?
¿Fue útil?

Solución

Depende del GC que esté usando su Java. Los GC paralelos podrían funcionar mejor en configuraciones de memoria más grandes, aunque no soy un experto en eso.

En general, si tiene una memoria más grande, menos frecuente debe ser GC-ed: hay mucho espacio para basura. Sin embargo, cuando se trata de un GC, el GC tiene que trabajar en más memoria, lo que a su vez podría ser más lento.

Otros consejos

El argumento -Xmx define el tamaño máximo de memoria que el montón puede alcanzar para la JVM. Debe conocer bien su programa y ver cómo funciona bajo carga y establecer este parámetro en consecuencia. Un valor bajo puede causar OutOfMemoryExceptions o un rendimiento muy bajo si la memoria de almacenamiento dinámico de su programa está alcanzando el tamaño máximo de almacenamiento dinámico. Si su programa se ejecuta en un servidor dedicado, puede establecer este parámetro más alto porque no afectará a otros programas.

El argumento -Xms establece el tamaño de memoria de almacenamiento dinámico inicial para la JVM. Esto significa que cuando inicie su programa, la JVM asignará esta cantidad de memoria al instante. Esto es útil si su programa consumirá una gran cantidad de memoria de almacenamiento dinámico desde el principio. Esto evita que la JVM aumente constantemente el montón y puede obtener algo de rendimiento allí. Si no sabe si este parámetro lo ayudará, no lo use .

En resumen, este es un compromiso que debe decidir basándose únicamente en el comportamiento de la memoria de su programa.

He descubierto que en algunos casos demasiada memoria puede ralentizar el programa.

Por ejemplo, tenía un motor de transformación basado en hibernación que comenzó a funcionar lentamente a medida que aumentaba la carga. Resultó que cada vez que obtuvimos un objeto de la base de datos, hibernate estaba verificando la memoria en busca de objetos que nunca serían utilizados nuevamente.

La solución fue desalojar los objetos antiguos de la sesión.

Stuart

  1. La asignación siempre depende de su sistema operativo. Si asigna demasiada memoria, podría terminar cargando porciones en el intercambio, lo que de hecho es lento.
  2. Si su programa se ejecuta más lento o más rápido depende de las referencias que la VM debe manejar y limpiar. El GC no tiene que barrer la memoria asignada para encontrar objetos abandonados. Sabe que son objetos y la cantidad de memoria que asignan por mapeo de referencia. Por lo tanto, el barrido solo depende del tamaño de sus objetos. Si su programa se comporta igual en ambos casos, el único impacto en el rendimiento debería estar en el inicio de la máquina virtual, cuando la máquina virtual intenta asignar la memoria proporcionada por su sistema operativo y si utiliza el intercambio (que nuevamente conduce a 1.)

Es difícil decir cómo la asignación de memoria afectará su velocidad. Depende del algoritmo de recolección de basura que esté utilizando la JVM. Por ejemplo, si su recolector de basura necesita hacer una pausa para hacer una recolección completa, entonces si tiene 10 más memoria de la que realmente necesita, entonces el recolector tendrá 10 basura más para limpiar.

Si está utilizando java 6, puede usar jconsole (en el directorio bin del jdk) para adjuntarlo a su proceso y observar cómo se comporta el recopilador. En general, los recopiladores son muy inteligentes y no necesitará realizar ningún ajuste, pero si lo necesita, existen numerosas opciones que puede utilizar para ajustar aún más el proceso de recopilación.

> C:\java -X

-Xmixed           mixed mode execution (default)
-Xint             interpreted mode execution only
-Xbootclasspath:<directories and zip/jar files separated by ;>
                  set search path for bootstrap classes and resources
-Xbootclasspath/a:<directories and zip/jar files separated by ;>
                  append to end of bootstrap class path
-Xbootclasspath/p:<directories and zip/jar files separated by ;>
                  prepend in front of bootstrap class path
-Xnoclassgc       disable class garbage collection
-Xincgc           enable incremental garbage collection
-Xloggc:<file>    log GC status to a file with time stamps
-Xbatch           disable background compilation
-Xms<size>        set initial Java heap size
-Xmx<size>        set maximum Java heap size
-Xss<size>        set java thread stack size
-Xprof            output cpu profiling data
-Xfuture          enable strictest checks, anticipating future default
-Xrs              reduce use of OS signals by Java/VM (see documentation)
-Xcheck:jni       perform additional checks for JNI functions
-Xshare:off       do not attempt to use shared class data
-Xshare:auto      use shared class data if possible (default)
-Xshare:on        require using shared class data, otherwise fail.

Las opciones -X no son estándar y están sujetas a cambios sin previo aviso.

(copiar y pegar)

Esta fue siempre la pregunta que tenía cuando trabajaba en una de mis aplicaciones que creaba una gran cantidad de hilos por solicitud.

Entonces, esta es una muy buena pregunta y hay dos aspectos de esto:
1. Si mis valores Xms y Xmx deberían ser iguales
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; la mayoría de los sitios web e incluso documentos de Oracle sugieren que sea lo mismo. Sin embargo, sugiero tener entre un 10 y un 20% de búfer entre esos valores para darle una opción de cambio de tamaño a su aplicación en caso de picos repentinos de alto tráfico O una pérdida de memoria incidental.

2. Si debo iniciar mi aplicación con un tamaño de almacenamiento dinámico menor
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; - Así que aquí está la cosa: no importa qué GC Algo use (incluso G1), el montón grande siempre tiene algo de compensación. El objetivo es identificar el comportamiento de su aplicación con respecto al tamaño de almacenamiento dinámico que puede permitir que su GC se detenga en términos de latencia y rendimiento.
   & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; - Por ejemplo, si su aplicación tiene muchos hilos (cada hilo tiene una pila de 1 MB en la memoria nativa y no en el montón) pero no ocupa mucho espacio de objetos, entonces sugiero tener un valor más bajo de Xms.
   & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; - Si su aplicación crea muchos objetos con un número creciente de hilos, identifíquese con qué valor de Xms usted se puede configurar para tolerar esas pausas STW. Esto significa identificar el tiempo de respuesta máximo de sus solicitudes entrantes que puede tolerar y ajustar el tamaño mínimo de almacenamiento dinámico.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top