2010-04-30 15 views
6

Estoy ejecutando un servidor de aplicaciones en Linux de 64 bits con 8 CPU centrales y 6 GB de memoria.Tuning JVM (GC) para aplicaciones de servidor de alta capacidad de respuesta

El servidor debe ser muy receptivo.

Después de una inspección descubrí que la aplicación que se ejecuta en el servidor crea una gran cantidad de objetos efímeros y solo tiene unos 200 ~ 400 MB de objetos de larga duración (siempre que no haya pérdida de memoria)

Después de leer http://java.sun.com/javase/technologies/hotspot/gc/gc_tuning_6.html utilizo estas opciones de JVM

-server -Xms2g -Xmx2g -XX:MaxPermSize=256m -XX:NewRatio=1 -XX:+UseConcMarkSweepGC 

Resultado: el GC menor toma 0,01 ~ 0,02 seg, la principal GC tarda 1 ~ 3 seg la GC menor sucede constantemente.

¿Cómo puedo mejorar o ajustar aún más la JVM?

tamaño de pila más grande? pero ¿tomará más tiempo para GC?

más grande NewSize y MaxNewSize (para la generación joven)?

otro colector? GC paralelo?

¿es una buena idea dejar que el GC principal tenga lugar con más frecuencia? ¿y cómo?

Respuesta

7

Resultado: el GC menor tiene 0,01 ~ 0,02 seg, la principal GC tarda 1 ~ 3 segundos al menor GC pasa constantemente.

A menos que esté informando pausas, diría que el recopilador de CMS está haciendo lo que le pidió que hiciera. Por definición, CMS utilizará un porcentaje mayor de la CPU que los colectores en serie y en paralelo. Esta es la multa que paga por los tiempos de pausa baja.

Si está viendo de 1 a 3 segundos pausa veces, yo diría que tiene que hacer algunos ajustes. No soy un experto, pero parece que debe comenzar reduciendo el valor de CMSInitiatingOccupancyFraction del valor predeterminado de 92.

Aumentar el tamaño del almacenamiento dinámico mejorará el "rendimiento" del GC. Pero si su problema es largas pausas, aumentar el tamaño del montón probablemente empeore el problema.

2

Puede que le interese probar la pausa baja Garbage-First collector en lugar del marcado simultáneo (aunque no es necesariamente más eficaz para todas las colecciones, se supone que tiene un mejor peor caso). Ha sido habilitado por -XX:+UseG1GC y se supone que es realmente una gran ventaja, pero es posible que desee realizar una evaluación exhaustiva antes de usarlo en producción. Probablemente ha mejorado desde entonces, pero parece haber sido un poco buggy hace un año, como se ve en Experience with JDK 1.6.x G1 (“Garbage First”)

+0

Me gustaría señalar que el Azul Zing jvm en muchos casos "es" más eficiente. Hacen gC detrás de escena mientras la aplicación se está ejecutando. Bastante genial. Nuevamente, no es gratis, pero para aquellos que deseen eliminar la necesidad de sintonizar una JVM, ésta puede hacerlo. Creo que lo llaman su colector C4 (concurrente, continuo, compactación, ¿coleccionista?). Un punto de referencia reciente de Mike McCandless lo probó en Apache Lucene/Solr contra CMS. Excelentes resultados en escalabilidad: http://blog.mikemccandless.com/2012/07/lucene-index-in-ram-with-azuls-zing-jvm.html He estado siguiendo esto ya que cambia el juego –

1

Está perfectamente bien que la recolección de basura se ejecute en paralelo con su programa, si tiene mucha CPU, lo cual hace.

Lo que quiere, es asegurarse de que no se encontrará con un escenario donde la recolección de basura PAUSA su programa principal.

¿Ha intentado simplemente no indicar ningún indicador excepto decir que quiere la VM del servidor (para Sun JVM), y luego poner su servidor bajo mucha carga para ver cómo se comporta?Solo entonces podrá ver si obtiene alguna mejora al jugar con las opciones.

1

Esto realmente suena como una aplicación de rendimiento y probablemente debería usar el colector de rendimiento. Equilibraría el tamaño del nuevo gen haciéndolo lo suficientemente grande como para no GC demasiado a menudo y lo suficientemente pequeño como para evitar largas pausas. 20ms suena como un GC menor largo para mí. También sospecho que tu espacio de superviviente está configurado demasiado grande y solo se está desperdiciando. Si no tienes mucha supervivencia a la generación anterior, no deberías haber sobrevivido tanto tus GC menores.

Al final, debe usar jvmstat y VisualGC para realmente tener una idea de cómo su aplicación está utilizando la memoria.

2

Cuidado ... GC puede ser un tema peludo si no tiene cuidado. Dentro de cualquier tiempo de ejecución (JVM para Java/CLR para .Net) hay varios procesos que tienen lugar. En general, hay una optimización de la memoria en etapas tempranas (Young Generational Garbage Collection/Young Gen GC & Old Generational Garbage Collection/Old Gen GC). El gen gc joven ocurre regularmente y se lo suele atribuir a sus pausas/hipo más pequeños. La antigua generación de gc es normalmente lo que está sucediendo cuando se ven las largas pausas de "detener el mundo".

¿Por qué usted puede ser que pregunte? La razón por la que obtiene pausas con su tiempo de ejecución/JVM es que cuando el tiempo de ejecución realiza su limpieza del Heap, tiene que pasar por lo que se denomina un cambio de fase. Detiene los hilos que ejecutan su aplicación para marcar e intercambiar punteros para optimizar su memoria disponible. Yong gen es más rápido ya que libera principalmente objetos que son solo temporales. La generación anterior, sin embargo, evalúa todos los objetos en el montón y cuando te quedas sin memoria se activará para liberar la memoria que tanto se necesita.

¿Por qué la precaución? La vieja generación empeora exponencialmente en el tiempo de pausa, cuanto más montón usas. con un tamaño de pila total de 2-4 GB, debería estar bien en tiempos de ejecución modernos como Java 6 (JDK 1.6+). Una vez que vaya más allá de ese límite, verá aumentos exponenciales en los tiempos de pausa. Me he encontrado con algunos clientes que tienen que reiniciar los servidores, ya que en algunos casos excepcionales en que un montón es grande, los tiempos de pausa del GC pueden llevar más tiempo que un reinicio completo.

Existen algunas herramientas nuevas que son geniales y que le pueden dar una punta de lanza en la evaluación de si el GC es su dolor. JHiccup es uno y es gratis desde el sitio web azulsystems. En este momento, creo que es solo para Linux. También tienen una JVM que tiene un algoritmo GC reconstruido que se ejecuta sin pausa ... pero si estás en una implementación de servidor único con una aplicación no crítica, puede que no sea rentable (esa no es gratis).

En resumen: si su tiempo de ejecución/JVM/CLR es menos de 2 GB, agregar más memoria ayudará. Asegúrate de darte un poco de sobrecarga. Si es posible, nunca desea alcanzar el 100% del tamaño de Heap/Memory. Es entonces cuando las largas pausas son las más largas. Date un 20% más de memoria sobre lo que crees que necesitarás. De esta forma, tienes espacio para que los algoritmos de GC muevan objetos para su optimización. Si alguna vez planea ir en grande ... hay una herramienta que arregla la tecnología JVM circa 1990 (Azul Systems Zing JVM), pero no es gratis. Ofrecen una herramienta de código abierto para diagnosticar problemas de GC. JVM (como lo he probado) también tiene una herramienta de visibilidad de nivel de hilos realmente genial que le permite informar sobre fugas, errores o bloqueos en la producción sin gastos generales (algún truco con la descarga de datos que la JVM ya maneja y estampación de tiempo). Eso ha ahorrado toneladas de tiempo de prueba de desarrollo ... pero nuevamente, no para aplicaciones pequeñas.

Permanezca debajo de 4 GB. Dar espacio libre adicional. Y si se desea se puede activar estas banderas para controlar GC para Java/JVM:

java -verbose:gc myProgram 
java -Xloggc:D:/log/myLogFile.log -XX:+PrintGCDetails myProgram 

Usted puede probar algunos de los otros colectores utiliza hotspot. Hay más de uno

Si está en Linux, intente con la herramienta JHiccup también. Es gratis.

1

Para aplicaciones de servidor de alta capacidad de respuesta, creo que desea ver que el GC principal ocurre con menos frecuencia. Aquí está la lista de parámetros ayudaría.

-XX: + CMSParallelRemarkEnabled
-XX: + CMSScavengeBeforeRemark
-XX: + UseCMSInitiatingOccupancyOnly
-XX: CMSInitiatingOccupancyFraction = 50
-XX: CMSWaitDuration = 300000
-XX: GCTimeRatio = 40

El tamaño de montón más grande puede no ser útil en pausa baja, siempre y cuando la aplicación no se quede sin memoria.

Nuevo más grande y MaxNewSize ayudaría en el rendimiento, puede que no ayude en la pausa baja. Si elige seguir este enfoque, puede considerar otorgar a los subprocesos de GC más tiempo de ejecución configurando -XX: GCTimeRatio más bajo. El punto es recordar tomar un holístico al sintonizar JVM.

0

Creo que los carteles anteriores han omitido algo muy obvio: el tamaño de Perm Generation es demasiado bajo. Si el sistema usa 200 a 400 MB como generación permanente, entonces puede ser mejor configurar Max Perm Gen en 400 MB. el tamaño PerGen también debe establecerse en el mismo valor. Entonces nunca se quedará sin espacio de generación permanente.

Actualmente, parece que la JVM tiene que pasar mucho tiempo moviendo objetos dentro y fuera de la Generación permanente. Esto puede llevar tiempo. JVM intenta asignar áreas de memoria contigua a objetos Java; esto acelera el acceso a la memoria debido a las características de nivel de hardware. Para hacer eso, es muy útil tener suficiente buffer en la memoria. Si la Generación permanente está casi llena, los objetos permanentes recién descubiertos se deben dividir o los objetos existentes se deben barajar. Esto es lo que desencadena un GC completo, además de provocar pausas completas largas del GC.

La pregunta indica que el tamaño de la Generación permanente ya se ha medido; si esto no se ha hecho, debe medirse con una herramienta. Estas herramientas procesan los registros generados por la JVM con la opción verboseGC activada.

Todas las opciones de marca y barrido mencionadas anteriormente pueden no ser necesarias con esta mejora básica.

Las personas utilizan las opciones de GC como soluciones sin evaluar qué tan maduras han demostrado ser en uso real.

+0

Creo que están confundidos acerca de la Generación Permanente. No contiene objetos, contiene definiciones de clase, metadatos de clase, etc. –

Cuestiones relacionadas