Nel precedente articolo sull’argomento dei performance monitoring tools (vedere articolo monitoring jvm) abbiamo trattato il concetto di JVM, fondamentale in ambito di applicazioni Java, e offerto una panoramica delle funzionalità di monitoring della JVM presenti nell’APM Glowroot.
Vedremo ora nei prossimi articoli due casi concreti di come l’indagine interna alla JVM effettuata all’interno del Laboratorio di Sme.UP abbia consentito di risolvere due rilevanti problemi di perfomance.
In questa parte tratteremo dell’esame dell’heap dump in situazioni critiche, nel successivo ci concentreremo sull’esame del thread dump.
Heap della JVM
L’heap della JVM è l’area di memoria in cui risiedono gli oggetti Java. Quando un’applicazione Java crea un oggetto esso viene memorizzato nell’heap. Esso può poi essere referenziato da altri oggetti all’interno dell’applicazione. Periodicamente viene effettuato un processo di garbage collection (letteralmente raccolta dei rifiuti) che ripulisce l’heap da oggetti non più in uso, facendo spazio a nuovi oggetti. Un oggetto è in uso quando è referenziato, ovvero quando parti dell’applicazione mantengono ancora un puntamento a quell’oggetto.
L’utilizzo dell’heap nella JVM segue generalmente il cosiddetto sawtooth pattern (comportamento a dente di sega). La memoria sale progressivamente per la creazione di nuovi oggetti. La maggioranza di tali oggetti hanno solitamente una vita breve quindi quando passa la garbage collection (per esattezza quella denominata di Major GC) la memoria viene liberata dagli oggetti non più utilizzati e il grafico mostra una ripida caduta.
Nella seguente immagine è mostrato un andamento di una memoria in salute.
Immagine 1 – Heap in buona salute
Fonte: https://plumbr.io/blog/memory-leaks/memory-leaks-fallacies-and-misconceptions
Un andamento come quello nella figura sottostante è invece indicativo di una memoria non in buona salute e in particolare della presenza di un memory leak. Qui l’occupazione minima di memoria dopo il passaggio della garbage collection sale costantemente nel tempo. Se l’applicazione rimane attiva per periodi di tempo prolungato l’area di memoria occupata tenderà progressivamente a crescere finchè prima o poi l’heap verrà saturato. Quando l’heap arriva ad alti livelli di saturazione si possono manifestare anche problemi di alta cpu, perchè il sistema cerca di effettuare la garbage collection con maggiore frequenza e sforzo, senza esito.
In una situazione del genere il riavvio dell’application server Java (o chiaramente dell’intera macchina su cui è hostata l’applicazione) risolve momentaneamente il problema, ma ovviamente una soluzione del genere è solo temporanea perchè il problema si riverificherà ancora col passare del tempo. Inoltre il riavvio di un server o di una macchina in sistemi non clusterizzati può generare disagi anche gravi dato che l’applicazione rimane momentaneamente indisponibile.
Immagine 2 – Heap in presenza di memory leak
Fonte: https://plumbr.io/blog/memory-leaks/memory-leaks-fallacies-and-misconceptions
Heap dump e strumenti di analisi
I grafici dell’andamento dell’heap possono dare indicazioni sulla presenza di un memory leak ma non danno informazioni sulla sua causa. Per individuarla si può ricorrere al dump (scarico) della memoria. Questo processo salva la memoria su un file che può essere analizzato con appositi strumenti. Uno dei più completi si chiama Eclipse Memory Analyzer (MAT) (https://www.eclipse.org/mat/), un progetto rilasciato sotto licenza Open Source e concepito appositamente per l’analisi di dumps dell’heap.
Eclipse Memory Analyzer dispone di molte features. Tra le più utili citiamo il Dominator Tree.
Esso mostra gli oggetti che occupano maggior memoria nell’heap secondo una struttura gerarchica in cui i sottolivelli sono gli oggetti referenziati dai padri. Grazie ad esso è possibile investigare quali oggetti ne tengono vivi altri perchè li referenziano.
Altre features interessanti sono il Top Consumers, che mostra gli oggetti più ingombranti raggruppati per classe e il Leak Suspects, una analisi dei leak sospetti eseguita sulla base degli anti patterns più conosciuti riguardanti l’uso della memoria.
Nel prossimo articolo parleremo di un caso reale di Memory Leak.
Se vuoi rimanere aggiornato anche sulle scorse puntate eccole:
- Introduzione ai performance monitoring tool – parte 1
- Esempio di un APM open source per un’app web Java J2EE: Glowroot – parte 2
- Glowroot – Profilazione e transazioni web – parte 3
- Glowroot Slow traces – parte 4
- Glowroot: monitoring della JVM – parte 5
Chiara Zambelli
Responsabile CI/CD – smeup
My LinkedIn Profile
Naviga per categoria:
Seleziona una categoria d’interesse dal nostro magazine