2011-08-31 4 views
53

Ho un dump di heap JVM HotSpot che vorrei analizzare. La VM ha funzionato con -Xmx31g e il file di heap heap è di 48 GB.Strumento per analizzare grandi discariche di heap Java

  • Non voglio nemmeno provare jhat, in quanto richiede circa cinque volte la memoria heap (che sarebbe 240 GB nel mio caso) ed è terribilmente lento.
  • Eclipse MAT si blocca con un ArrayIndexOutOfBoundsException dopo aver analizzato il dump dell'heap per diverse ore.

Quali altri strumenti sono disponibili per tale attività? Una suite di strumenti a riga di comando sarebbe la soluzione migliore, costituita da un programma che trasforma il dump dell'heap in efficienti strutture di dati per l'analisi, combinate con diversi altri strumenti che funzionano sui dati pre-strutturati.

+0

Sei sicuro che il dump non sia corrotto e che tu stia utilizzando una versione più recente dei JAR DTFJ? Le caratteristiche di 'ArrayIndexOutOfBoundsException' in atleast [two] (https://bugs.eclipse.org/bugs/show_bug.cgi?id=294311) [bug] (https://bugs.eclipse.org/bugs/show_bug.cgi ? id = 307.530). Lo sto affermando perché non hai riportato [un OOME durante l'esecuzione di MAT, che ha una correzione diversa] (http://wiki.eclipse.org/MemoryAnalyzer/FAQ#Out_of_Memory_Error_while_Running_the_Memory_Analyzer). –

+0

jhat usa heapMap per memorizzare gli oggetti letti, che cresce esponenzialmente con il numero di oggetti memorizzati nell'heap. Un'opzione è di cambiare il decl da heapMap a TreeMap ed eseguire la dimensione heap di jhat almeno grande quanto il processo. – codeDr

risposta

40

Normalmente, quello che uso è incluso nell'importo ParseHeapDump.shEclipse Memory Analyzer e descritti here, e lo faccio su una i nostri server più rinforzati (scarica e copia su linux .zip distro, decomprimi qui). Lo script della shell richiede meno risorse rispetto all'analisi dell'heap dalla GUI, inoltre è possibile eseguirlo sul tuo server con più risorse (puoi allocare più risorse aggiungendo qualcosa come -vmargs -Xmx40g -XX:-UseGCOverheadLimit alla fine dell'ultima riga dello script. Per esempio, l'ultima riga del file potrebbe assomigliare a questo dopo la modifica

./MemoryAnalyzer -consolelog -application org.eclipse.mat.api.parse "[email protected]" -vmargs -Xmx40g -XX:-UseGCOverheadLimit 

gestire l'iT come ./path/to/ParseHeapDump.sh ../today_heap_dump/jvm.hprof

dopo che riesce, si crea un certo numero di file "indice" accanto al file .hprof.

Dopo aver creato gli indici, provo a generare valuta i rapporti da quel punto e scarica quei rapporti sulle mie macchine locali e prova a vedere se riesco a trovare il colpevole proprio da quello (non solo i rapporti, non gli indici). Ecco un tutorial su creating the reports.

esempio di report:

./ParseHeapDump.sh ../today_heap_dump/jvm.hprof org.eclipse.mat.api:suspects 

Altre opzioni di rapporto:

org.eclipse.mat.api:overview e org.eclipse.mat.api:top_components

Se tali relazioni non sono sufficienti e se ho bisogno di un po 'di scavo (vale a dirediciamo via oql), scp gli indici oltre al file hprof sulla mia macchina locale, e poi apro il dump dell'heap (con gli indici nella stessa directory del dump dell'heap) con la mia GUI di Eclipse MAT. Da lì, non ha bisogno di troppa memoria per essere eseguito.

EDIT: mi piaceva aggiungere due note:

  • Per quanto ne so, solo la generazione degli indici è la parte di memoria ad alta intensità di Eclipse MAT. Dopo aver ottenuto gli indici, la maggior parte dell'elaborazione da parte di Eclipse MAT non richiederebbe molta memoria.
  • Fare questo su uno script di shell significa che posso farlo su un server headless (e di solito lo faccio anche su un server headless, perché normalmente sono i più potenti). E se si dispone di un server in grado di generare un dump dell'heap di tale dimensione, è probabile che sia disponibile un altro server in grado di elaborare anche gran parte del dump dell'heap.
+2

Nota importante: 'ParseHeapDump.sh' è fornito solo con la versione Linux, non con la versione OSX - http://www.eclipse.org/mat/downloads.php – Christopher

+0

Quando provo questo (ssh'd per bash su una macchina Linux), fallisce immediatamente con "Impossibile inizializzare GTK +". Quindi sembra (la versione attuale, 15-04-2016) pensa ancora che stia parlando con un'interfaccia utente (?). –

+2

Hmm, le versioni più recenti di ParseHeapDump.sh vogliono eseguire direttamente ./MemoryAnalyzer. Sto sperimentando con l'avvio del launcher direttamente con java, finora sembra funzionare, ad es. java-jar -Xmx16g -Xms16g plugins/org.eclipse.equinox.launcher_1.3.100.v20150511-1540.jar -consoleLog -consolelog -l'applicazione org.eclipse.mat.api.parse "$ @" –

5

La risposta accettata a questa domanda correlata dovrebbe fornire un buon inizio per voi (usa jmap vivo istogrammi invece di discariche heap):

Method for finding memory leak in large Java heap dumps

maggior parte degli analizzatori altro mucchio (io uso IBM http://www.alphaworks.ibm.com/tech/heapanalyzer) richiederebbe meno una percentuale di RAM in più rispetto all'heap se ti aspetti uno strumento GUI piacevole.

Oltre a questo, molti sviluppatori utilizzano approcci alternativi, come l'analisi dello stack in tempo reale per avere un'idea di cosa sta succedendo.

Anche se devo chiedermi perché i tuoi cumuli sono così grandi? L'effetto sull'assegnazione e sulla raccolta dei rifiuti deve essere massiccio. Scommetto una grande percentuale di ciò che è nel vostro mucchio dovrebbe in realtà essere memorizzati in un database/persistente della cache ecc ecc

3

Suggerisco di provare YourKit. Di solito ha bisogno di un po 'meno di memoria rispetto alla dimensione del dump dell'heap (lo indicizza e usa tali informazioni per recuperare quello che vuoi)

2

Uno strumento non molto conosciuto - http://dr-brenschede.de/bheapsampler/ funziona bene per grandi quantità. Funziona campionando in modo che non debba leggere l'intera cosa, anche se un po 'pignola.

+0

Sfortunatamente si dice "problema comune: esaurimento della memoria: aumentare il -Xmx a 2/3 della dimensione del dump" ma suppongo che tu abbia abbastanza RAM o può eseguirlo su un server con abbastanza, che potrebbe essere sufficiente, grazie! – rogerdpack

1

In caso di utilizzo di MAT su MAC (OSX) si avrà il file MemoryAnalyzer.ini in MemoryAnalyzer.app/Contents/MacOS. Non stava funzionando per me. È possibile creare un comando di avvio/script di shell modificato in base al contenuto di questo file ed eseguirlo da tale directory. Nel mio caso ho voluto 20 GB mucchio:

./MemoryAnalyzer -startup ../../../plugins/org.eclipse.equinox.launcher_1.3.100.v20150511-1540.jar --launcher.library ../../../plugins/org.eclipse.equinox.launcher.cocoa.macosx.x86_64_1.1.300.v20150602-1417 -vmargs -Xmx20g --XX:-UseGCOverheadLimit -Dorg.eclipse.swt.internal.carbon.smallFonts -XstartOnFirstThread 

basta eseguire il comando/script da Contents/MacOS directory attraverso il terminale, per avviare l'interfaccia grafica con più RAM a disposizione.

3

alcune opzioni in più:

Questa persona http://blog.ragozin.info/2015/02/programatic-heapdump-analysis.html

scritto un Netbeans analizzatore mucchio personalizzato che solo espone un'interfaccia "stile query" attraverso il file dump heap, in realtà invece di caricare il file nella memoria.

https://github.com/aragozin/jvm-tools/tree/master/hprof-heap

Anche se non so se "il suo linguaggio di query" è meglio che l'OQL eclissi menzionato nella risposta accettata qui.

JProfiler 8.1 ($ 499 per licenza utente) è anche said per poter attraversare cumuli di grandi dimensioni senza utilizzare molti soldi.

+0

Attualmente funziona su una discarica grande, a differenza di https://github.com/on-site/fasthat. Bello! –