2009-07-23 22 views
11

Abbiamo trasformato la registrazione GC verbose per tenere traccia di una perdita di memoria conosciuto e ha ottenuto le seguenti voci nel registro:Che cosa significa "GC--" in un log di raccolta dati inutili java?

... 
3607872.687: [GC 471630K->390767K(462208K), 0.0325540 secs] 
3607873.213: [GC-- 458095K->462181K(462208K), 0.2757790 secs] 
3607873.488: [Full GC 462181K->382186K(462208K), 1.5346420 secs] 
... 

Capisco il primo e il terzo di quelli, ma che cosa fa il "GC- - "uno significa?

+2

Dato il timestamp e le quantità di memoria, suppongo che abbia eseguito una garbage collection ma abbia perso memoria disponibile (perché altri oggetti sono stati creati in parallelo) – Yishai

+0

Yishai, grazie, ha molto senso. Non sono sicuro se sia giusto o no, ma potrebbe essere molto bene. – RodeoClown

+0

Vuoi metterlo in una risposta in modo che io possa votarlo/accettarlo? :) – RodeoClown

risposta

12

ho avuto questo tipo di linee nella mia uscita gc:

44871.602: [GC-- [PSYoungGen: 342848K->342848K(345600K)] 961401K->1041877K(1044672K), 0.1018780 secs] [Times: user=0.16 sys=0.00, real=0.11 secs] 

ho letto la risposta di Yishai e non avrebbe molto senso, ma ho voluto vedere con i miei occhi nel codice sorgente di Java GC, quando la JVM stampa "-" nel registro GC e perché.

Perché a mia conoscenza "scavenging Parallelo" del giovane Gen è un GC stop-il-mondo, quindi non ci non potrebbe essere oggetti creati parallelamente a questo GC. (Vedi https://blogs.oracle.com/jonthecollector/entry/our_collectors)

È possibile trovare questo nel codice sorgente JDK (vedi http://hg.openjdk.java.net/jdk7/jdk7) g1CollectedHeap.cpp e psScavenge.cpp

jdk7-ee67ee3bd597/hotspot/src/share$ egrep -h -A2 -B5 -r '"\-\-"' * 
# G1 Collector 
if (evacuation_failed()) { 
    remove_self_forwarding_pointers(); 
    if (PrintGCDetails) { 
    gclog_or_tty->print(" (to-space overflow)"); 
    } else if (PrintGC) { 
    gclog_or_tty->print("--"); 
    } 
} 
-- 
# Parallel Scavenge Collector 
promotion_failure_occurred = promotion_failed(); 
if (promotion_failure_occurred) { 
    clean_up_failed_promotion(); 
    if (PrintGC) { 
    gclog_or_tty->print("--"); 
    } 
} 

Motivo GC-- con il parallelo scavenging Collector

il giovane GC ha rilevato un errore di promozione (vedi http://mail.openjdk.java.net/pipermail/hotspot-gc-use/2010-March/000567.html):

Un fallimento di promozione è una scavenger che non ha successo perché non c'è abbastanza spazio nel vecchio gen per fare tutte le promozioni necessarie. Lo scavenger è in sostanza slegato e quindi viene eseguita una compattazione STW completa dell'intero heap.

'Non c'è abbastanza spazio' non significa necessariamente che non c'è abbastanza spazio nel vecchio, ma che il vecchio spazio è molto frammentato (vedi http://blog.ragozin.info/2011/10/java-cg-hotspots-cms-and-heap.html):

[ ...] è impossibile trovare una certa quantità di memoria continua per promuovere un particolare oggetto grande, anche se il numero totale di byte liberi è abbastanza grande.

Queste due opzioni JVM potrebbe aiutare ad analizzare la tua frammentazione heap (vedi http://blog.ragozin.info/2011/10/java-cg-hotspots-cms-and-heap.html):

-XX:+PrintPromotionFailure 
-XX:PrintFLSStatistics=1 

Motivo GC-- con il G1 di raccolta

Un fallimento di evacuazione con il G1 è quando una Regione Survivor non ha abbastanza spazio per gli oggetti sopravvissuti di una Regione giovane.

Non so se G1 Collector risponde a un errore di evacuazione con un GC completo oppure no.

+0

Beh, sembra abbastanza definitivo :) – RodeoClown

0

Non è in Java GC FAQ

http://java.sun.com/docs/hotspot/gc1.4.2/faq.html

Né è qualcosa di simile accennato nella pagina esempi GC Java

http://java.sun.com/docs/hotspot/gc1.4.2/example.html

non ho mai visto prima.

Avete in esecuzione uno speciale Garbage Collector? Che VM stai correndo? Si verifica sempre prima del GC completo? Stai chiamando System.gc()?

+0

Ciao e5, nessun raccoglitore di rifiuti speciali. Normale Sun VM. Lo vedo solo occasionalmente, quindi no, non è prima di ogni Full GC (ma non potrei dire se ogni volta che si verifica è direttamente prima di uno). No System.gc(). – RodeoClown

1

ho ottenuto il seguente da here:

Le prime due righe indicare aveste due collezioni minori e una maggiore uno. I numeri prima e dopo la freccia indicano la dimensione combinata di oggetti live prima e dopo la raccolta di immondizia , rispettivamente. Dopo minori collezioni conteggio include oggetti che non sono necessariamente vivo ma non può essere recuperato, o perché essi sono direttamente vivi, o perché sono all'interno o citati dalla generazione tenured. Il numero in parentesi s il disponibile spazio totale, senza contare lo spazio nella generazione permanente, che è la totale mucchio meno uno Il formato raccolta importante nella terza riga è simile. La bandiera -XX: + PrintGCDetails stampa informazioni aggiuntive sulle collezioni. Le informazioni aggiuntive stampate con questo flag è passibile di modifica con ogni versione della macchina virtuale. L'output aggiuntivo con il flag -XX: + PrintGCDetails cambia in particolare con le esigenze dello sviluppo della macchina Java Virtual . degli spazi sopravvissuti. La raccolta minore ha richiesto circa un quarto di di secondo.

0

Yishai detto nei commenti:

Dato il timestamp e la memoria ammonta direi che ha eseguito una garbage collection, ma ha perso la memoria disponibile (perché gli altri oggetti sono stati creati in parallelo)

1

In realtà, dopo averlo incontrato nei nostri registri, un collega e io abbiamo una spiegazione alternativa che sembra adattarsi più strettamente ai fatti.

In questo esempio noterete che un GC completo segue questa linea GC secondaria. Posso confermare che questo è sempre il caso quando si presenta nei nostri registri. Puoi anche vedere che la dimensione iniziale e finale della Young Gen è uguale, e posso confermare ancora che è sempre così.

Crediamo che ciò che sta accadendo qui sia che la VM ha avviato un GC Minore e, dopo non essere in grado di liberare nulla o di spendere troppo tempo senza poter liberare nulla, decide invece di fare un Full.

Problemi correlati