2012-02-23 7 views
6

Estamos ejecutando varias instancias de un proceso de servidor en un cuadro de Linux. La caja tiene 8 núcleos y 16 gb de RAM. Estoy comenzando cada proceso con la opción -Xincgc, usando Java 1.6.Java Garbage Collection detiene todos los procesos de Java

Tenemos varios temporizadores equipados a lo largo de la aplicación que rastrean el tiempo para completar varias tareas. Cuando ocurre una recolección de basura, noto que cada proceso de java en el cuadro muestra que cualquier tarea que estaba ejecutando en ese momento era lenta.

No se estanca durante mucho tiempo, tal vez 100-300ms más o menos, pero la latencia es un factor importante para esto. Tampoco se estanca constantemente, solo periódicamente.

Cuando se produce la recolección de basura, ¿detiene el proceso de java en cualquier momento? Si es así, ¿hay alguna forma de evitar esto? ¿Debo usar diferentes opciones de GC?

ACTUALIZACIÓN:

Para que quede claro, no estoy preocupado por un estancamiento del proceso mientras GC está sucediendo. Puedo ajustar la configuración u optimizar para ese caso. Me pregunto por qué TODOS los procesos Java en ejecución parecen detenerse al mismo tiempo cuando pensé que eran más o menos independientes.

+0

GC en realidad no debería detener todos los procesos. Además, debe leer la [guía de sintonización de GC] (http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html). El recolector de basura predeterminado para Java 6 debe ser el GC paralelo, que está optimizado para el rendimiento, no para el tiempo de pausa. El coleccionista simultáneo podría ser un mejor ajuste. – millimoose

+0

Es posible que desee considerar la agrupación de objetos. Esa sería una forma de reducir la cantidad de GC que está sucediendo. –

+1

@Guaranteed: ¿está ejecutando JVM independientes y cuando una JVM realiza un GC completo, todas las JVM individuales se ven afectadas? ¿Es esto lo que describes? – TacticalCoder

Respuesta

0

La latencia de GC es uno de los problemas inherentes a los lenguajes recolectados de basura como Java. Esta es una de las razones por las que los sistemas de alta velocidad como los sistemas de negociación de acciones se escriben en C++ y no en Java o C#. 100 ms suena perfecto para una operación grande de GC.

+2

¿Cómo responde esto la pregunta? Todo lo que dice es que sí, lo que el OP describió de hecho está sucediendo; ya lo sabemos. – millimoose

+0

Creo que la pregunta era más acerca de procesos * múltiples * estancamiento al mismo tiempo. – delnan

+0

@Mike Thomsen: algos de trading de alta frecuencia escritos en C++? Pfft ... Eso es tan ssllooww! ¡Ahora está directamente Lenguaje de descripción de hardware/FPGAs! ;) – TacticalCoder

0

Si utiliza una herramienta como JConsole para ver su actividad de memoria, verá que la recolección de basura generalmente es una actividad de gran peso. Es posible que desee hacer algunos perfiles para ver si hay otros cuellos de botella involucrados. Además, la mayoría de los algoritmos de recolección de basura tienen bastantes opciones de configuración disponibles para ellos.

Por último, recuerdo que una situación con la que nos hemos enfrentado hace bastante tiempo nos llevó a descubrir que tener las configuraciones de memoria mínima y máxima juntas era útil (al menos en nuestro caso). Causó recolección de basura más frecuente, pero no fueron tan intrusivos.

Espero que esto ayude.

3

cuando se utiliza -Xincgc, según esta sun documentation

El colector concurrentes bajo pausa: este colector se utiliza si el -Xincgc ™ o -XX: + UseConcMarkSweepGC se pasa en la línea de comandos. El recopilador concurrente se usa para recopilar la generación de tenencia y realiza la mayor parte de la recopilación de forma simultánea con la ejecución de la aplicación. La aplicación está en pausa durante períodos cortos durante la colección.

Es posible que debas considerar otras alternativas como Rendimiento de colector. La documentación anterior tiene una buena descripción de cuándo, qué coleccionista será útil.

+0

Si leo esa documentación correctamente, el recopilador de rendimiento es aún menos adecuado para un requisito de pausa baja: TODOS los recopiladores pausarán a veces, solo difieren en cuánto tiempo va a ser cada pausa y cuánto del tiempo total de ejecución se gastará en pausas. AFAIK, el colector de rendimiento tendrá pausas individuales más largas, pero tardarán menos tiempo en el final. El recopilador incremental tendrá pausas más cortas que acumularán más tiempo de inactividad. – millimoose

+0

Además, la guía a la que se vinculó es para Java 5.0. Los recolectores de basura están disponibles/seleccionados de manera predeterminada es una cosa que cambia entre las versiones de la máquina virtual de HotSpot, por lo que definitivamente debe utilizar la documentación relevante más actual al hablar de ellos. – millimoose

3

Se supone que Java v 1.6 es inteligente y determina qué tipo de GC es el mejor.

me gustaría recomendar la lectura de este: Garbage collection in Java 6

Resumen: Prueba cualquiera de ellos (pero no ambos):

  • -XX: + UseParallelGC
  • -XX: + ExplicitGCInvokesConcurren
2

El problema con el que se encuentra es una "Colección completa de basura", también conocida como "Stop the world GC". Cuando esto ocurre, la aplicación Java deja de funcionar de manera básica. Marque este tema por algunos punteros:

Tuning garbage collections for low latency

+0

Según los registros de GC, no se están realizando colecciones completas. – Guaranteed

Cuestiones relacionadas