visual vertical uiswing tutorial setborder layouts javase fillers docs crear con borde java garbage-collection jvm heap performance

vertical - swing fillers java



¿Puede Sun JVM manejar tamaños de montón gigantescos sin problemas, y cómo? (7)

# 1. Dado el siguiente caso, ¿cómo ajustarías la configuración del montón y del GC?

En primer lugar, tener 64 gigabytes de memoria no implica que tenga que usarlos todos para una JVM. En realidad, más bien significa que puedes ejecutar muchos de ellos. Entonces, es imposible responder a su pregunta sin ningún acceso a su máquina y aplicación para medir y analizar cosas (saber lo que hace su aplicación no es suficiente). Y no, no estoy pidiendo acceso a tu entorno :)

# 2. ¿Habría muestras notables (pausas de JVM, etc.) que serían notadas por los usuarios finales?

El objetivo del ajuste es encontrar un buen compromiso entre la frecuencia y la duración de los GC (principales). Con un montón de ~ 55g, la GC no será frecuente, pero tomará un tiempo notable , con seguridad (cuanto mayor sea el montón, más largo será el GC principal). El uso de un colector de basura concurrente o simultáneo ayudará en los sistemas multiprocesador, pero no resolverá por completo este problema. ¿Por qué necesita ~ 55g (esto es mega ultra enorme para una IMO de una aplicación web), esa es mi pregunta. Prefiero ejecutar muchas JVM en clúster para manejar la carga si es necesario (en algún momento, la base de datos se convertirá en el cuello de botella de todos modos con una aplicación orientada a datos).

# 3. ¿De verdad esto debería funcionar? Creo que debería.

Hmm ... no estoy seguro de obtener la pregunta. ¿Qué es " esto "? ¿Instanciando una JVM con un gran montón? Sí, debería. ¿Es equivalente a ejecutar varias JVM? No, ciertamente no.

PS: 4G es el límite máximo de almacenamiento teórico para la JVM de 32 bits que se ejecuta en un sistema operativo de 64 bits (consulte ¿Por qué no puedo obtener un montón más grande con la JVM de 32 bits? )

PPS: en las máquinas virtuales de 64 bits, tiene 64 bits de direccionabilidad para trabajar, lo que da como resultado un tamaño máximo de almacenamiento dinámico de Java limitado solo por la cantidad de memoria física y espacio de intercambio que proporciona su sistema. (ver ¿Qué tamaño puedo crear con una máquina virtual de 64 bits? )

He escuchado a varias personas alegando que no se puede escalar el tamaño del montón de JVM. He oído reclamos sobre el límite práctico de 4 gigabytes (escuché decir a un consultor de IBM), 10 gigabytes, 32 gigabytes, etc. ... Simplemente no puedo creer ninguno de esos números y me he estado preguntando sobre el problema. ahora por un tiempo

Entonces, tengo una pregunta de tres partes que espero que alguien con experiencia pueda responder:

  1. Dado el siguiente caso, ¿cómo ajustarías la configuración del montón y del GC?
  2. ¿Habría muestras notables (pausas de JVM, etc.) que serían notadas por los usuarios finales?
  3. ¿De verdad esto debería funcionar? Creo que debería.

El caso:

  • Plataforma de 64 bits
  • 64 núcleos
  • 64 gigabytes de memoria
  • El servidor de aplicaciones está orientado al cliente (es decir, servidor de aplicaciones web Jboss / tomcat): las pausas completas de JVM probablemente serían notadas por los usuarios finales
  • Sun JVM, probablemente 1.5

Para demostrar que no les pido que hagan mi tarea, esto es lo que se me ocurrió:

  1. -XX:+UseConcMarkSweepGC -XX:+AggressiveOpts -XX:+UnlockDiagnosticVMOptions -XX:-EliminateZeroing -Xmn768m -Xmx55000m
  2. CMS debería reducir la cantidad de pausas, aunque viene con gastos generales. Las otras configuraciones para CMS parecen predeterminarse automáticamente a la cantidad de CPU para que me parezcan cuerdas. El resto que agregué son extras que pueden ser buenos o malos en general para el rendimiento, y probablemente deberían probarse.
  3. Seguro.

Como Chris Rice ya escribió, no esperaría ningún problema obvio con el GC para tamaños de almacenamiento de hasta 32-64 GB, aunque puede haber algún punto de la lógica de la aplicación, lo que puede causar problemas.

No está directamente relacionado con GC, pero aún así le recomendaría que realice una prueba de carga realista en su sistema de producción. Solía ​​trabajar en un proyecto, donde teníamos una configuración similar (configuración de JBoss / Tomcat relativamente grande y en clúster para servir a una aplicación web pública) y sin exagerar, JBoss no se está comportando muy bien con mucha carga o con un alto número de concurrentes llama si está utilizando EJB. JBoss está pasando mucho tiempo en bloques sincronizados al acceder y administrar los conjuntos de instancias EJB y, si opta por un clúster, incluso esperará la comunicación de la red dentro del clúster dentro de estos bloques sincronizados. Tenga especialmente en cuenta la replicación de estado con un rendimiento deficiente, si está utilizando SFSB.


Creo que será difícil para cualquiera darles algo más que consejos generales, sin tener más conocimiento de su aplicación.

Lo que sugeriría es que use VisualGC (o el complemento VisualGC para VisualVM ) para ver realmente qué está haciendo la recolección de elementos no utilizados cuando se está ejecutando su aplicación. Una vez que tenga una mayor comprensión de cómo funciona el GC junto con su aplicación, será mucho más fácil sintonizarlo.


He encontrado que la arquitectura de memoria juega un papel importante en los tamaños de memoria grandes. Las aplicaciones en general no funcionan tan bien si usan más de un banco de memoria. La JVM parece sufrir también, especialmente el GC que tiene que barrer toda la memoria.

Si tiene una aplicación que no cabe en un banco de memoria, su aplicación tiene que extraer memoria que no es local para un procesador y usar memoria local para otro procesador.

En Linux, puede ejecutar numactl --hardware para ver el diseño de los procesadores y los bancos de memoria.


Obviamente, el tamaño del almacenamiento dinámico no es ilimitado y cuanto mayor es el tamaño del almacenamiento dinámico, más pasará su JVM en GC. Aunque creo que es posible establecer el tamaño del almacenamiento dinámico bastante alto en JVM de 64 bits, todavía creo que no es realmente práctico. El consejo aquí es mejor tener varias JVMs ejecutándose con los mismos parámetros, es decir, un clúster de nodos JBoss / Tomcat ejecutándose en la misma máquina física y obtendrá un mejor rendimiento.

EDITAR : también su comportamiento GC depende de la taxonomía de su montón. Si tiene muchos objetos de vida corta y cada solicitud al servidor crea muchos de ellos, su GC recogerá mucha basura con mucha frecuencia y, por lo tanto, en un gran tamaño de pila, se producirán pausas más largas. Si tiene muchos objetos de larga vida (p. Ej., Almacenar en caché la mayoría de sus datos en la memoria) y la cantidad de objetos de vida corta no es tan grande, entonces es mejor tener un tamaño de pila mayor.


Dependiendo de su análisis de pausa del GC, es posible que desee implementar el modo Incremental por el cual la pausa larga puede interrumpirse durante un período de tiempo.


Solo para agregar algunos interruptores más que usaría de manera predeterminada: -Xms55g puede ayudar a reducir el tiempo de rampa porque libera a Java de la necesidad de verificar si puede volver al tamaño inicial y también permite un mejor dimensionamiento inicial interno de las áreas de memoria.

Además, hicimos buenas experiencias con NewSize para darle un tamaño grande y joven para deshacerse de la basura a corto plazo: -XX: NewSize = 1g Además, la mayoría de las webapps crean una gran cantidad de basura a corto plazo que nunca sobrevivirá el procesamiento de solicitudes. Incluso puedes hacer eso más grande. Con Xms55g, la máquina virtual ya se reserva una gran parte. Tal vez reducir el tamaño puede ayudar.

-Xincgc ayuda a limpiar la generación joven de forma incremental y devuelve la CPU a menudo a los hilos del usuario.

-XX: CMSInitiatingOccupancyFraction = 70 Si realmente llena toda esa memoria, intente iniciar la recolección de basura CMS antes.

-XX: + CMSIncrementalMode pone el CMS en modo incremental para devolver la CPU a los hilos del usuario con más frecuencia.

Adjunte al proceso con jstat -gc -h 10 <pid> 1s y observe el funcionamiento del GC.

¿Realmente llenarás la memoria? Supongo que 64cpus para el procesamiento de solicitudes incluso podría funcionar con menos memoria. ¿Qué almacena allí?