2012-07-05 11 views
20

He encontrado un caso CG bastante confuso: Mientras que el espacio Eden está 100% lleno, se utiliza el espacio 0% de sobreviviente. Cuando el Edén está lleno, la recolección de basura debe ser desencadenada, ¿verdad?100% espacio Eden total, 0% espacio usado Survivor - Recolección de basura no hecha

¿Puede haber un caso en el que el daemon del GC no se pueda ejecutar? Como una CPU al 100%?

Estamos usando jdk-1.7.

¿Cuál puede ser la causa? A continuación se muestra la salida jmap.

También tratamos de capturar un uso de memoria más detallado usando jmap -histo -F, pero luego el uso de CPU cayó a 0% y el proceso de java se volvió inalcanzable.

using thread-local object allocation. 
Parallel GC with 18 thread(s) 

Heap Configuration: 
    MinHeapFreeRatio = 40 
    MaxHeapFreeRatio = 70 
    MaxHeapSize  = 12884901888 (12288.0MB) 
    NewSize   = 1310720 (1.25MB) 
    MaxNewSize  = 17592186044415 MB 
    OldSize   = 5439488 (5.1875MB) 
    NewRatio   = 2 
    SurvivorRatio = 8 
    PermSize   = 21757952 (20.75MB) 
    MaxPermSize  = 85983232 (82.0MB) 
    G1HeapRegionSize = 0 (0.0MB) 

Heap Usage: 
PS Young Generation 
Eden Space: 
    capacity = 4265738240 (4068.125MB) 
    used  = 4265738240 (4068.125MB) 
    free  = 0 (0.0MB) 
    100.0% used 
From Space: 
    capacity = 14352384 (13.6875MB) 
    used  = 0 (0.0MB) 
    free  = 14352384 (13.6875MB) 
    0.0% used 
To Space: 
    capacity = 14680064 (14.0MB) 
    used  = 0 (0.0MB) 
    free  = 14680064 (14.0MB) 
    0.0% used 
PS Old Generation 
    capacity = 8589934592 (8192.0MB) 
    used  = 8589931920 (8191.997451782227MB) 
    free  = 2672 (0.0025482177734375MB) 
    99.99996889382601% used 
PS Perm Generation 
    capacity = 41353216 (39.4375MB) 
    used  = 41079056 (39.17604064941406MB) 
    free  = 274160 (0.2614593505859375MB) 
    99.33702858805468% used 
+1

¿Ha supervisado el volcado de hilo? ¿Hay algo sospechoso? – Sabya

+0

También tratamos de capturar un uso de memoria más detallado usando jmap -histo -F, pero luego el uso de la CPU cayó a 0% y el proceso de java se volvió inalcanzable. – kuloglan

+0

le recomendamos que use visualvm en este escenario. – Sabya

Respuesta

2

Sólo un pensamiento, pero veo que la vieja generación también está llena. ¿Podría ser que el GC en lugar de tratar de limpiar Eden está ocupado ejecutando GC completo tratando de limpiar la generación anterior para evitar OOM.

9

cuando veo a su configuración Montón encontré que

MaxNewSize = 17592186044415 MB es incorrecto sin embargo, debe ser en bytes.

Lo que veo es que casi todas las generaciones están llenas y al mismo tiempo y Collector está tratando de recopilar las dos generaciones para que se bloqueen entre sí.

Sugiero que por favor ajuste la memoria con los parámetros a continuación.

-XX:NewRatio=3 - the young generation will occupy 1/4 the overall heap 
-XX:NewSize - Calculated automatically if you specify -XX:NewRatio 
-XX:MaxNewSize - The largest size the young generation can grow to (unlimited if this value is not specified at command line) 

también sugieren utilizar un poco de espacio sobreviviente que dará colector momento en el que los objetos se copian de eden en generación 'tenured'.

-XX:SurvivorRatio=6 - each survivor space will be 1/8 the young generation 

Si los espacios de supervivientes son demasiado pequeños, la copia se desborda directamente en la generación permanente.

Para cualquier aclaración refiera this enlace.

Editar:

-XX:NewRatio=3 - la generación joven ocupará 1/4 el montón general

Cálculo:

y/t=1/3 

    y+t=h 
    y+3y=h 
    y=h/4 

t=tenured 
y=young 
h=heap 
+0

La salida de jmap para MaxNewSize es incorrecta: http://bugs.sun.com/bugdatabase/view_bug.do;jsessionid=bc3bd27567a528d86286ee4991b?bug_id=6792386 – kuloglan

+0

Si configuro -XX: NewRatio = 3, la generación joven ocupará 3/4 el montón general, NO 1/4, ¿estoy en lo cierto? – kuloglan

+0

@kuloglan No si establecemos -XX: NewRatio = 3 significa que la proporción entre la generación joven y la tenencia es de 1: 3 eso significa que parte de la generación joven será 1/4 – amicngh

5

El hilo buffers locales se asignan desde el espacio eden . Tan pronto como se asigna un búfer, el espacio libre en el espacio eden se reduce por completo. Esto puede significar que tiene muchos TLAB que están casi vacíos, pero el espacio de eden parece estar lleno. Un GC se activa cuando no hay suficiente espacio libre en el espacio de eden.

Si desactivas TLAB -XX:-UseTLAB, esto disminuirá el rendimiento pero obtendrás una contabilidad muy precisa de cómo se usa el espacio.

1

SurvivorRatio Cálculo:

Si SurvivorRatio = 6, entonces la relación de (una SurvivorSpace: Eden) = (1: 6).
Así que dos Supervivientes tomarán (2 partes), y Eden tiene 6 partes. Tan total 8 partes
Así que si tengo un gen joven de 40 MB, Eden es (6/8 * 40) MB y un superviviente tendrá (1/8 * 40) MB.

Si SurvivorRatio = 7. Entonces, las partes totales son (7 + 1 + 1 = 9). Eden es (7/9 * 40) MB y sobreviviente tendrán (1/9 * 40) MB

Teóricamente

The SurvivorRatio parameter controls the size of the two survivor spaces. 
For example, -XX:SurvivorRatio=6 sets the ratio between each survivor space 
and eden to be 1:6, each survivor space will be one eighth of the young 
generation. 

Mathamatically

S - Sobreviviente
E - Eden
Y - Generación joven

if SurvivorRatio=6 
then S/E = 1/6 
     E = 6S 

2S + E = Y 
2S + 6S = Y 
S = Y/8 

Efecto

Si el aumento de más resultados de valor SurvivorRatio en menor espacio para Survivor resultados, empujando el espacio eden objetos directamente en el viejo/titular gen. Menor oportunidad de filtrar objetos en vivo en Survivor Space mediante GC menor. También esto puede aumentar el no de GC completo.

Si disminuye esto a un valor más bajo, los resultados en un espacio de eden menor harán que el GC menor sea frecuente.

Tenga en cuenta que el tiempo necesario para GC menor será más especial si estamos utilizando un algoritmo de CG serial donde solo se utilizará un hilo para GC, aunque su máquina es de núcleo múltiple.

También tenga en cuenta que -XX:+UseAdaptiveSizePolicy determinará el propio SurvivorRatio de JVM durante el tiempo de ejecución, pero siempre es mejor mencionarlo manualmente en función de su aplicación probando la ejecución de carga múltiple.

Cuestiones relacionadas