Sintomi

L’applicazione java funziona più lentamente e alla fine esaurisce la memoria oppure visualizzi un errore nei log o nell’output della console OutOfMemoryError: Java heap space o OutOfMemoryError: gc overhead limit exceeded.

Causa

Tali problemi possono avere molte cause.

Una possibile causa è che l’applicazione java, nel nostro caso, CRX / CQ è stata avviata dalla riga di comando con le impostazioni di memoria heap predefinite di Java. Questo significa che il parametro jvm -Xmx non è stato specificato. CRX o CQ hanno bisogno di almeno 256 MB di memoria heap assegnati per l’esecuzione. Se questo è il problema, allora, a partire dalla riga di comando, assicurati che le impostazioni della memoria heap siano impostate. Esempio:

java -Xmx512m -jar *.jar

Se non è questo il caso, allora l’applicazione potrebbe mantenere troppi oggetti senza rilasciarli per la raccolta oggetti inattivi. Questa è chiamata perdita di memoria, vedi qui per maggiori informazioni. Vedi la sezione sottostante su come analizzare i problemi di memoria nelle applicazioni java.

Analisi, soluzione

Crea un’immagine heap

Genera un’immagine heap automaticamente

Per creare automaticamente un’immagine heap quando si esaurisce la memoria, puoi aggiungere il parametro jvm -XX:+HeapDumpOnOutOfMemoryError per generare automaticamente un’immagine heap quando l’applicazione genera un OutOfMemoryError. Per esempio,

java -Xmx256m -XX:+HeapDumpOnOutOfMemoryError -jar *.jar

Questo genera un file immagine heap (java_....hprof) nella directory di lavoro del processo ogni volta che il processo java esaurisce la memoria. Il processo può continuare a funzionare anche dopo che è stata generata l’immagine heap. Di solito, è sufficiente un solo file di immagine heap per analizzare il problema.

Nota: se stai usando lo script crx-quickstart/server/start per avviare un’istanza CRX, puoi aggiungere poi -XX:+HeapDumpOnOutOfMemoryError alla variabile CQ_JVM_OPTS (assicurati che anche la variabile sia decommentata). Per esempio:

CQ_JVM_OPTS='-XX:+HeapDumpOnOutOfMemoryError'

Dopo aver aggiunto questo parametro e riavviato l’istanza di CRX, verifica che sia impostata la nuova opzione jvm. Esegui ps -ef | grep java dalla riga di comando. Poi controlla se vedi -XX:+HeapDumpOnOutOfMemoryError come parametro del processo CRX java.

Se hai bisogno di specificare una cartella diversa per generare l’immagine heap a causa delle restrizioni di spazio su disco, allora puoi aggiungere il parametro -XX:HeapDumpPath=/path/to/to/generate/heapdump per dire a jvm dove collocare il file.

Vedi qui per un riferimento ai parametri jvm relativi al debug.

Genera un’immagine heap manualmente

Sun/Oracle JVM

Per generare manualmente un’immagine heap, esegui questo comando (jmap e jps si trovano nella cartella bin della home directory jdk):

  1. cerca il pid del processo java per il quale stai generando un’immagine heap.
    • In Unix o Linux questo può essere fatto con ps -ef | grep java o jps -l
    • In Windows questo può essere fatto aprendo task manager, premi Ctrl+Shift+Esc quindi vai in Visualizza => Seleziona colonne => PID (Process Identifier) o jps -l
  2. Esegui il comando jmap qui sotto, sostituisci /path/to/generate/heapdumpfile.hprof con la posizione in cui desideri generare il file immagine heap, e sostituisci 1234 con il pid che hai cercato nel passaggio precedente.
    jmap -dump:format=b,file=/path/to/generate/heapdumpfile.hprof 1234
    

IBM JVM

Prima di tutto dovrai cambiare le impostazioni predefinite JVM per quanto riguarda gli agenti di immagine, per generare le immagini corrette al segnale utente. Ci sono diversi tipi di immagine, ma  generalmente è necessaria l’intera immagine di stistema per eseguire un’analisi approfondita della memoria. Aggiungi le seguenti argomentazioni:

Xdump:heap:opts=PHD+CLASSIC:events=user -Xdump:system:events=user

Questo evento “utente” si verifica quando JVM riceve il segnale SIGQUIT (Linux, AIX®, z/OS®, and i5/OS™) o SIGBREAK (Windows) dal sistema operativo.

Per ulteriori informazioni, consulta qui la documentazione fornitore.

Attenzione: I file immagine heap sono grandi e possono avere le stesse dimensioni su disco della configurazione dei parametri heap -Xmx jvm massima. Assicurati di avere abbastanza spazio su disco assegnato alla directory in cui viene generato il file di immagine.

Analizza l’immagine heap

Un buon strumento per analizzare le immagini heap è EclipseMAT (Eclipse Memory Analyzer): http://www.eclipse.org/mat/

Questo strumento non può analizzare le immagini generate da JVM IBM. Per quelle, ci sono diverse possibilità. IBM HeapAnalyzer funziona bene per le immagini heap in formato PHD o classico.

Per un’analisi completa dell’immagine di sistema, utilizza IBM Support Assistant Workbench , con strumenti di monitoraggio e diagnostica IBM per Java - Memory Analyzer versione 1.2 installato sulla parte superiore.

Istogramma heap

L’istogramma heap è una semplice misurazione del numero di oggetti live e della memoria utilizzata per classe Java. Purtroppo, a seconda dell’installazione di Java, gli strumenti necessari potrebbero non essere disponibili o potrebbero non funzionare sempre. Per creare un istogramma heap, è necessario prima l’id di processo del processo Java. Per ottenerlo, esegui ps o (se disponibile), esegui:

jps -l

Questo strumento Java ottiene gli ID di processo di tutti i processi Java in esecuzione. Esempio:

327 3332 sun.tools.jps.Jps 3313 crx-quickstart-....jar

Esegui ora il comando seguente:

jmap -histo 3313

L’elenco è ordinato a seconda della memoria totale richiesta (base: esclusi gli oggetti di riferimento). Le prime 20 righe dell’output sono le più interessanti. Esempio di output:

La versione di JVM è 1.5.0_20-141 con iterazione su heap. Questo potrebbe richiedere un po’ di tempo..... Attenzione: saltare TLAB non valido per thread t@62211 Attenzione: saltare TLAB non valido per thread t@62467 ... Descrizione della classe conteggio dimensioni ------------------------------------------------------- 10592904 12916 byte[] 10285840 75255 * ConstMethodKlass 6283176 58388 char[] 6042304 14928 int[] 4995752 116201 * SymbolKlass 4220896 75255 * MethodKlass 4196512 6969 * ConstantPoolKlass 2928560 6969 * InstanceKlassKlass 2631008 6066 * ConstantPoolCacheKlass 2395872 149742 org.apache.jackrabbit.core.query.lucene.DocId$PlainDocId 1476008 7003 java.util.HashMap$Entry[] 1396128 58172 java.lang.String 1070232 44593 java.util.HashMap$Entry 753984 10036 short[] 735464 54 org.apache.jackrabbit.core.query.lucene.DocId[] 720192 7502 java.lang.Class 640704 13348 com.day.crx.persistence.tar.index.IndexEntry ...

Informazioni aggiuntive

Per aiutare ad analizzare il problema, abbiamo anche bisogno di conoscere le seguenti informazioni:

  • Versione CRX o CQ, incluso un elenco dei numeri di tutte le versioni di correzioni rapide installate.
  • Sistema operativo, fornitore di JVM e versione.

Riferimenti

[1] http://java.sun.com/javase/6/webnotes/trouble/TSG-VM/html/memleaks.html
[2] http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp#DebuggingOptions

Questo prodotto è concesso in licenza in base alla licenza di Attribuzione-Non commerciale-Condividi allo stesso modo 3.0 Unported di Creative Commons.  I post su Twitter™ e Facebook non sono coperti dai termini di Creative Commons.

Note legali   |   Informativa sulla privacy online