2014-09-12 17 views
6

enter image description herePS Old Gen in Heap utilizzo della memoria: le impostazioni GC

Qui di seguito sono le mie impostazioni JVM:

JAVA_OPTS=-server -Xms2G -Xmx2G -XX:MaxPermSize=512M -Dsun.rmi.dgc.client.gcInterval=1200000 -Dsun.rmi.dgc.server.gcInterval=1200000 -XX:+UseParallelOldGC -XX:ParallelGCThreads=2 -XX:+UseCompressedOops -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jbos88,server=y,suspend=n 

Problema: totale della memoria heap: 2GB Old Gen: 1.4GB (2/3 di Heap) New Gen: 600 MB (1/3 di Heap)

The Old Gen cresce in memoria oltre il 70% 0f della sua dimensione allocata e non è mai sottoposto a GC anche al 100% cioè 1,4 GB. Si può vedere il grafico sotto i picchi e mai GC, il calo della memoria è quando è stato forzato a GC dalla JConsole. Questo problema sta alla fine portando giù il web server.

Qualcosa che mi manca o che imposta erroneamente la JVM?

Grazie per l'aiuto in anticipo.

Aggiornamento mia interrogazione:

Dopo l'analisi mucchio appare come stateful session bean è il primo sospettato: enter image description here Abbiamo session bean stateful che tengono la logica di persistenza assistito da Hibernate.

+0

vedi la terminazione JVM con 'OutOfMemoryError Heap Space'? o ti stai aspettando che il vecchio GC di gen venisse eseguito prima? –

risposta

3

enter image description here I bean di sessione stateful stavano rendendo la memoria JVM esaurita. La gestione in modo esplicito utilizzando l'annotazione @Remove ha risolto il problema.

+0

Come l'hai trovato? – Nageswaran

4

Il GC verrà chiamato alla fine, il vecchio gen non viene quasi mai chiamato (perché è estremamente lento). Il Gc funziona, ma all'inizio funziona solo con il gen nuovo e il gen di sopravvissuto, ha un algoritmo completamente diverso per la pulizia del vecchio gen che è più lento delle gens nuove/sopravvissute.

Questi numeri sono davvero alti, il vecchio non dovrebbe mai raggiungere un numero elevato rispetto al nuovo. La mia ipotesi è che tu abbia una perdita di memoria.

Posso solo supporre che il programma abbia a che fare con file di grandi dimensioni, probabilmente si sta risparmiando su riferimenti a lungo termine.

3

Anche continua ad avere il problema principale (perdita di memoria) risolto, se si vuole ancora il vecchio gen per essere eliminato nei frequenti pause di piccole dimensioni, si può provare a impostare

-XX:MaxGCPauseMillis=(time in millis) 

e questo è applicabile solo con Parallel Collector e quando la politica di ridimensionamento adattivo è attiva. Per impostazione predefinita, la politica di ridimensionamento adattivo è attiva, ma, se si desidera menzionarlo in modo esplicito, è possibile utilizzarlo.

-XX:+UseAdaptiveSizePolicy 

Oppure è possibile passare al CMS collettore dove è possibile utilizzare

-XX:CMSInitiatingOccupancyFraction=(% value) 
-XX:+UseCMSInitiatingOccupancyOnly 

che è un modo più affidabile di raccogliere la vecchia generazione quando ha raggiunto una certa frazione della vecchia generazione.

+0

Ho provato questi parametri JVM e apparentemente GC non è in grado di liberare il vecchio spazio gen e continua a cercare di liberare la memoria per sempre ogni volta in grado di recuperare a malapena qualsiasi memoria. – amitsalyan

+0

Se la memoria non viene ripristinata in modo significativo dopo un intero gc, allora ciò che è nel tuo vecchio gen non è spazzatura. In tal caso, questo può essere l'impronta della memoria dell'applicazione. In tal caso, dovresti considerare di aumentare la memoria totale allocata. Supponendo Session Stateful I bean sono i principali occupanti della memoria, direi che la memoria del piede di stampa è approssimativamente uguale a (velocità di creazione di nuove sessioni * timeout di sessione * dimensione media di una sessione) –

+0

Perché non condividere l'altra analisi di heap dopo aver fatto le ottimizzazioni (annotazione @Remove)? quindi avrò un quadro migliore della situazione. Mi piacerebbe vedere l'output di jmap -histo: live

Problemi correlati