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
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ì:
vecchio spazio di utilizzo:
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.
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. –
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
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. –