2015-03-06 15 views
7

Sto eseguendo un sistema di compilazione. Usavamo il collector CMS, ma abbiamo iniziato a soffrire con cicli GC completi molto lunghi, il throughput (il tempo che non faceva GC) era di circa il 90%. Così ho deciso ora di passare a G1 con l'ipotesi che, anche se avessi tempo di GC complessivo più lungo, le pause saranno più brevi e quindi garantirò una maggiore disponibilità. Quindi questa idea sembrava funzionare ancora meglio di quanto mi aspettassi, non vedevo GC completo per quasi 3 giorni, il throughput era del 97%, le prestazioni generali del GC erano decisamente migliori. (Tutte le catture schermo ei dati ricavati in GCViewer)Le pause GC diventano molto lunghe dopo diversi giorni

Normal

Fino ad ora (giorno 6). Oggi il sistema è semplicemente diventato berzerk. Il vecchio spazio utilizzato è appena sotto il 100%. Sto vedendo completa GC innescato quasi ogni 2-3 minuti o giù di lì: Berzerk!

vecchio spazio di utilizzo: Old space

spazio Heap 20G (128G Ram totale). Le bandiere che sto attualmente utilizzando sono:

-XX:+UseG1GC 
-XX:MaxPermSize=512m 
-XX:MaxGCPauseMillis=800 
-XX:GCPauseIntervalMillis=8000 
-XX:NewRatio=4 
-XX:PermSize=256m 
-XX:InitiatingHeapOccupancyPercent=35 
-XX:+ParallelRefProcEnabled 

più flag di registrazione. Quello che mi sembra che manchi è -XX:+ParallelGCThreads=20 (ho 32 processori), il valore predefinito dovrebbe essere 8. Ho anche letto da oracle che sarebbe suggerito di avere -XX:+G1NewSizePercent=4 per heap 20G, il valore predefinito dovrebbe essere 5.

Sto usando Java HotSpot (TM) Server VM a 64 bit 1.7.0_76, Oracle Corporation

Che cosa suggeriresti? Ho degli errori evidenti? Cosa cambiare? Sono avido dando solo Java 20G? L'assunto qui è che dargli troppa ammonizione significherebbe un GC più lungo in quanto c'è semplicemente più da pulire (logica contadina).

PS: L'applicazione non è mia. Per me è un prodotto in scatola.

+5

Penso che ci sia qualche perdita di memoria da qualche parte nel tuo sofware, che lentamente consumerà lo spazio disponibile, rendendo il lavoro del GC sempre più difficile con il passare del tempo. Quindi, la soluzione non deve essere cercata nell'algoritmo GC o nelle impostazioni dell'heap (che alla fine andrà a riempire indipendentemente dalle sue dimensioni). Devi aggiustare il tuo software o vivere con il fatto che devi riavviarlo ogni tanto. È interessante notare che sembra che il tuo heap non si riempirà completamente, bloccando il tuo programma, quindi forse ho sbagliato. –

+0

Si dovrebbe incollare un registro GC stampato con '-XX: + PrintGCDetails -XX: + PrintGCTimeStamps -XX: + PrintAdaptiveSizePolicy -Xloggc: ', che sarà più utile per comprendere le decisioni di G1. Se è possibile, dovresti provare java 8, G1GC ha subito molti cambiamenti da allora. Molte delle sue euristiche sono state migliorate e alcuni colli di bottiglia rimossi. IIRC in 7 ci sono alcuni casi in cui G1 può ordinare "dipingersi in un angolo" – the8472

+0

Ho trovato una soluzione, Il sistema consente inoltre agli utenti di eseguire script personalizzati durante il processo di compilazione. Dopo un'indagine (molto lunga), si è scoperto che un utente eseguiva costantemente uno script, che non rilasciava la memoria, causando il costante aumento della linea di base dell'heap, quindi il ciclo GC veniva rilasciato sempre meno ogni volta. –

risposta

1

Che cosa suggeriresti? Ho degli errori evidenti? Cosa cambiare? Sono goloso dando Java solo a 20G? L'assunto qui è che dargli troppa ammonizione significherebbe un GC più lungo in quanto c'è semplicemente più da pulire (logica contadina).

Se si innesca piena GC, ma i vostri soggiorni di occupazione vicino a quelli da 20 GB, allora è possibile che il GC semplicemente non ha abbastanza spazio per respirare, sia per soddisfare la domanda di enormi assegnazioni o di o di incontrare alcuni dei suoi obiettivi (il throughput , pause), forzando i GC completi come riserva.

Quindi, è possibile aumentare il limite di heap o attenuare gli obiettivi di velocità effettiva.

Come accennato in precedenza nel mio commento si può anche provare l'aggiornamento a java8 per una migliore euristica G1.

Per ulteriori consigli, i registri GC che coprono il comportamento "berzerk" sarebbero utili.