Pregunta

Desde Java 7 se va a utilizar la nueva recolección de basura G1 por defecto de Java se va a ser capaz de manejar un orden de magnitud más grande del montón sin supuestos tiempos GC pausa "devastadores"? ¿Alguien se ha puesto efectivamente en práctica G1 en la producción, ¿cuáles fueron sus experiencias?

Para ser justos la única vez que he visto realmente pausas largas GC está en muy grandes montones, mucho más que una estación de trabajo tendría. Para aclarar mi pregunta; G1 se abra la puerta de entrada a montones en los cientos de GB? TB?

¿Fue útil?

Solución

Parece que el punto de G1 es tener tiempos de pausa más pequeños, incluso hasta el punto donde tiene la posibilidad de especificar un objetivo máximo tiempo de pausa.

La recolección de basura no es sólo un simple "Hola, es completa, vamos a pasar todo a la vez y empezar de nuevo" tratar más - es de varios niveles, el sistema increíblemente complejo, fondo roscado. Se puede hacer mucho de su mantenimiento en el fondo sin pausas en todo, y también utiliza el conocimiento de los patrones esperados del sistema en tiempo de ejecución para ayudar -. Como asumir la mayoría de los objetos morir justo después de haber sido creado, etc.

Yo diría que los tiempos de pausa GC van a seguir para mejorar, no empeorar, con versiones futuras.

EDIT:

en la re-lectura se me ocurrió que yo uso diario de Java - Eclipse, Azureus, y las aplicaciones que desarrollo, y ha sido un largo tiempo desde que vi una pausa. No es una pausa significativa, pero me refiero a cualquier pausa en absoluto.

He visto pausas cuando haga clic derecho en el Explorador de Windows o (a veces) cuando conecto un determinado hardware USB, pero con Java --- ninguno en absoluto.

Es GC sigue siendo un problema con alguien?

Otros consejos

He estado probando con una aplicación pesada: 60-70GB asignan a montón, con 20-50GB en uso en cualquier momento. Con este tipo de aplicaciones, es un eufemismo decir que su experiencia puede variar. Estoy corriendo JDK 1.6_22 en Linux. Las versiones menores se important-- antes acerca de 1.6_20, había bichos en G1 que causaron NullPointerExceptions al azar.

He encontrado que es muy bueno en mantener dentro de la pausa objetivo que le dan mayor parte del tiempo. El valor por defecto parece ser una (segunda 0,1) pausa de 100 ms, y lo he estado diciendo que haga que la mitad (-XX: MaxGCPauseMillis = 50). Sin embargo, una vez que se pone muy poca memoria, que entra en pánico y hace una colección llena de basura stop-el-mundo. Con 65GB, que dura entre 30 segundos y 2 minutos. (El número de CPU, probablemente, no hace una diferencia;. Que probablemente limitada por la velocidad del bus)

En comparación con el CMS (que no es el servidor predeterminado GC, pero debe ser para los servidores web y otras aplicaciones en tiempo real), pausas típicas son mucho más predecibles y se pueden hacer mucho más corto. Hasta ahora estoy teniendo más suerte con CMS para las grandes pausas, pero que puede ser al azar; Los estoy viendo sólo un par de veces cada 24 horas. No estoy seguro de cuál va a ser más apropiado en mi entorno de producción en el momento, pero probablemente G1. Si Oracle mantiene afinarlo, sospecho G1 será en última instancia el claro ganador.

Si usted no está teniendo un problema con los recolectores de basura existentes, no hay razón para considerar G1 en este momento. Si está ejecutando una aplicación de baja latencia, tales como una aplicación GUI, G1 es probablemente la mejor opción, con MaxGCPauseMillis establece realmente bajo. Si está ejecutando una aplicación en modo por lotes, G1 no le compra nada.

Aunque no he probado G1 en la producción, pensé que iba a comentar que los GC ya son problemáticos para los casos sin montones "gigantescos". servicios específicos con sólo, por ejemplo, 2 o 4 gigas pueden verse gravemente afectados por GC. GCs generación joven por lo general no son problemáticos, ya que terminan en milisegundos de un solo dígito (o como máximo de dos dígitos). Pero colecciones antigua generación son mucho más problemáticos, ya que llevan varios segundos con pasadas de generación tamaños de 1 GB o superior.

Ahora: en la teoría de la CMS puede ayudar mucho allí, ya que puede ejecutar la mayor parte de su funcionamiento al mismo tiempo. Sin embargo, con el tiempo habrá casos en los que no se puede hacer esto y tiene que recurrir a la colección "parar el mundo". Y cuando esto sucede (después de, por ejemplo, a 1 hora - no muy a menudo, pero todavía demasiado a menudo), bueno, aferrarse a su f *** ing sombreros. Se puede tomar un minuto o más. Esto es especialmente problemático para los servicios que tratan de limitar el máximo de latencia; en lugar de ello tomar, por ejemplo, 25 milisegundos para servir a una solicitud que ahora tarda diez o más segundos. Para añadir insulto lesión a los clientes a menudo será entonces el tiempo de espera de la solicitud y vuelva a intentar, lo que lleva a otros problemas (también conocido como "tormenta de mierda").

Esta es un área donde G1 se esperaba ayudar mucho. Trabajé para una gran empresa que ofrece servicios en la nube para el almacenamiento y envío de mensajes; y no podríamos utilizar CMS ya que si bien la mayor parte del tiempo que funcionó mejor que las variedades paralelas, que tenía estos colapsos. Así durante aproximadamente una hora las cosas estaban muy bien; y luego las cosas golpeó el ventilador ... y porque el servicio se basa en racimos, cuando un nodo se metió en problemas, los demás siguieron normalmente (ya que los tiempos de espera inducida por GC conducen a otros nodos creen nodo se había estrellado, lo que lleva a re-rutas).

No creo GC es que gran parte de un problema para aplicaciones, y tal vez incluso los servicios no agrupados se ven afectados con menor frecuencia. Pero cada vez más los sistemas se agrupan (esp., Gracias a los almacenes de datos NoSQL) y tamaños de almacenamiento dinámico están creciendo. OldGen GCs son super-linealmente relacionada con el tamaño del montón (lo que significa que la duplicación de tamaño de la pila más que duplica el tiempo GC, asumiendo que el tamaño de datos en vivo configurar también se duplica).

Azul de CTO, Gil Tene, tiene una buena visión general de los problemas asociados con la recolección de basura y una revisión de las distintas soluciones en su Recolección de basura la comprensión de Java y qué puede hacer al respecto presentación, y no hay detalles adicionales en este artículo: http://www.infoq.com/articles/azul_gc_in_detail .

C4 del colector de basura de Azul en nuestra Zing JVM es a la vez paralela y simultánea, y utiliza el mismo mecanismo de GC, tanto para los nuevos y viejos generaciones, trabajando al mismo tiempo y de compactación en ambos casos. Lo más importante, C4 no tiene parada al mundo caer de nuevo. Todo compactación se realiza simultáneamente con la aplicación en ejecución. Tenemos clientes que ejecutan muy grandes (cientos de GBytes) con peor de los casos los tiempos de pausa de GC <10 ms, y dependiendo de la aplicación a menudo menos de 1-2 ms.

El problema con CMS y G1 es que en algún punto de la memoria de pila Java debe ser compactada, y ambos de estos colectores de basura detener-el-mundo / STW (es decir, hacer una pausa en la aplicación) para llevar a cabo la compactación. Así, mientras que la CMS y G1 pueden empujar a cabo STW se detiene, que no los eliminan. C4 de Azul, sin embargo, no elimina completamente pausas STW y por eso Zing tiene tan baja GC pausas incluso para tamaños de almacenamiento dinámico gigantescos.

Y para corregir una declaración hecha en una respuesta anterior, Zing no requiere ningún cambio en el sistema operativo. Se ejecuta al igual que cualquier otra JVM en distribuciones de Linux sin modificar.

Ya estamos utilizando G1GC, desde hace casi dos años. Su haciendo muy bien en nuestra misión fundamental del sistema de procesamiento de transacciones, y resultó ser un gran apoyo w.r.t de alto rendimiento, bajas pausas, concurrencia y gestión de memoria optimizado pesada.

Estamos utilizando siguientes valores de JVM:

-server -Xms512m -Xmx3076m -XX:NewRatio=50 -XX:+HeapDumpOnOutOfMemoryError -XX:+UseG1GC -XX:+AggressiveOpts -XX:+UnlockExperimentalVMOptions -XX:MaxGCPauseMillis=400 -XX:GCPauseIntervalMillis=8000 -XX:+PrintGCTimeStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime

Actualización

-d64 -server -Xss4m -Xms1024m -Xmx4096m -XX:NewRatio=50 -XX:+UseG1GC -XX:+UnlockExperimentalVMOptions -XX:+HeapDumpOnOutOfMemoryError -XX:-DisableExplicitGC -XX:+AggressiveOpts -Xnoclassgc -XX:+UseNUMA -XX:+UseFastAccessorMethods -XX:ReservedCodeCacheSize=48m -XX:+UseStringCache -XX:+UseStringDeduplication -XX:MaxGCPauseMillis=400 -XX:GCPauseIntervalMillis=8000

El colector G1 reduce el impacto de colecciones completas. Si usted tiene una aplicación en la que ya ha reducido la necesidad de colecciones completas, el colector mapa barrido simultáneo es tan bueno y en mi experiencia tiene menores tiempos de recolección más cortos.

Parece que G1 a partir JDK7u4 finalmente está soportado oficialmente, consulte la RN para JDK7u4 http://www.oracle.com/technetwork/java/javase /7u4-relnotes-1575007.html.

A partir de nuestras pruebas todavía para grandes JVM sintonizados CMS todavía actúa mejor que el G1, pero supongo que va a crecer mejor.

CMS puede conducir a un rendimiento degradado lentamente incluso si lo está ejecutando sin acumular objetos permanentes. Esto es debido a la fragmentación de memoria que supuestamente evita G1.

El mito sobre G1 disponible sólo con soporte de pago es sólo eso, un mito. Sun y ahora Oracle haber aclarado esto en la página de JDK.

GC G1 se supone que funciona mejor. Pero si el establecimiento -XX: MaxGCPauseMillis demasiado agresiva, la basura se recogía con demasiada lentitud. Y es por eso GC completa activa en el ejemplo de David Leppik.

acabo implementado G1 recolector de basura en nuestro proyecto grande Memoria de terracota. Mientras se trabaja en diferentes tipos de colectores G1 nos dio los mejores resultados con menos de 600 ms tiempo de responder.

Puede encontrar los resultados de la prueba (26 en total) aquí

Espero que ayuda.

Recientemente se me ha pasado de

CMS a G1GC con 4G montón y procesador 8 de núcleo en los servidores con JDK 7.1.45 .

(JDK 1.8.x G1GC se prefiere más de 1,7, pero debido a algunas limitaciones, I tiene que pegarse a la versión 1.7.45)

He configurado por debajo de los parámetros clave y mantenido todos los otros parámetros a sus valores por defecto.

-XX:G1HeapRegionSize=n, XX:MaxGCPauseMillis=m, -XX:ParallelGCThreads=n, 
-XX:ConcGCThreads=n apart from -Xms and -Xmx

Si desea afinar estos parámetros, echar un vistazo a este Artículo oráculo .

Las principales observaciones:

  1. Uso de memoria es compatible con G1GC a diferencia de alta y bajas con CMS
  2. tiempo de pausa Max GC es menor en comparación con CMS
  3. El tiempo empleado en la recogida de basura es poco alto en comparación con G1GC CMS.
  4. El número de grandes colecciones son casi insignificantes en comparación con CMS
  5. El número de colecciones de menor importancia son el extremo más alto en comparación con CMS

Pero aún así estoy feliz de que Max GC tiempo de pausa es inferior a partir de la CMS. He puesto Max GC tiempo de pausa como 1,5 segundos y este valor aún no ha sido atravesado.

SE pregunta relacionada:

Java 7 (JDK 7 ) la recolección de basura y documentación sobre G1

He migrado recientemente parte de Twicsy a un nuevo servidor con 128 GB de RAM y decidió utilizar 1.7. Empecé usando las mismas configuraciones de memoria como lo hacía con 1,6 (tengo varias instancias en ejecución haciendo varias cosas, en cualquier lugar de 500mb del montón hasta 15 GB, y ahora una nueva con 40 GB) y que no funcionó bien en absoluto . 1.7 parece que usar más de 1,6 montón, y experimentaron una gran cantidad de problemas en los primeros días. Yo por suerte tenía un montón de memoria RAM para trabajar con y golpeado hasta la RAM para la mayoría de mis procesos, pero todavía estaba teniendo algunos problemas. Mi MO normal era utilizar una muy pequeña cantidad mínima montón de 16m, incluso con un máximo de almacenamiento dinámico de varios gigabytes, a continuación, encienda GC incrementales. Esto mantuvo las pausas en un mínimo. Eso no funciona ahora, sin embargo, y he tenido que aumentar el tamaño mínimo a acerca de lo que esperaba para usar en promedio en el montón, y que ha funcionado muy bien. Todavía he GC incrementales activada, pero voy a tratar sin. No se hace una pausa en absoluto ahora, y las cosas parecen estar corriendo muy rápido. Por lo tanto, creo que la moraleja de la historia es no espere que su configuración de memoria para traducir perfectamente desde 1.6 a 1.7.

G1, la demanda es mucho más ágil: el latancy de la aplicación elevará - la aplicación puede ser nombrado como "-tiempo real suave". Esto se hace mediante la sustitución de dos tipos de carreras pequeñas GC (los menores de edad y uno grande en Titular GEN) a los pequeños de igual tamaño.

Para más detalles vistazo a esto: http://geekroom.de/java/java-expertise-g1- fur-java-7 /

Estoy trabajando con Java, por Heap pequeños y grandes, y la cuestión de la GC y GC completa aparece todos los días, ya que las limitaciones pueden ser más estrictas que otras: en cierto entorno, 0,1 segundos de GC carroñero o completa GC, matar simplemente el fonctionnalité, y tienen la configuración de grano fino y la capacidad es importante (CMS, iCMS, otros ... el objetivo está aquí para tener el mejor tiempo de respuesta es posible con el tratamiento casi en tiempo real (aquí el tratamiento en tiempo real es a menudo 25 ms), por lo que, básicamente, cualquier mejora de la ergonomía GC heuristique ans son bienvenidos!

Yo uso G1GC en Java 8 y también con Groovy (también de Java 8), y estoy haciendo diversos tipos de cargas de trabajo, y fue demasiado G1GC funciona así:

  • El uso de la memoria es muy baja, por ejemplo, 100 MB en lugar de 500 MB en comparación con la configuración por defecto de Java

  • El tiempo de respuesta es consistente y muy baja

  • El rendimiento entre la configuración predeterminada y G1GC es 20% desaceleración cuando se utiliza G1GC en peor de los casos (sin sintonización, la aplicación de un solo subproceso). No es mucho considerando buen tiempo de respuesta y bajo uso de memoria.

  • Cuando se ejecuta de Tomcat que es multi-hilo, el rendimiento global es 30% mejor y uso de memoria es mucho menor en los tiempos de respuesta, así son mucho más bajos.

Así que en general, cuando se utiliza muy diversas cargas de trabajo, G1GC es muy buena colector para Java 8 para aplicaciones de subprocesos múltiples, e incluso para un único subproceso hay algunos beneficios.

No es sugiere utilizar java8 w / G1GC de cálculo de punto flotante con JVM punto de acceso similar. Es peligroso para la integridad y exactitud de la aplicación.

https://bugs.openjdk.java.net/browse/JDK-8148175

JDK-8165766

JDK-8186112

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