Tool zur Analyse großer Java-Heap-Dumps

80

Ich habe einen HotSpot JVM-Heap-Dump, den ich analysieren möchte. Die VM lief mit -Xmx31gund die Heap-Dump-Datei ist 48 GB groß.

  • Ich werde es nicht einmal versuchen jhat, da es ungefähr das Fünffache des Heapspeichers benötigt (das wären in meinem Fall 240 GB) und furchtbar langsam ist.
  • Eclipse MAT stürzt mit einem ab, ArrayIndexOutOfBoundsExceptionnachdem der Heap-Dump mehrere Stunden lang analysiert wurde.

Welche anderen Tools stehen für diese Aufgabe zur Verfügung? Am besten ist eine Reihe von Befehlszeilentools geeignet, die aus einem Programm bestehen, das den Heap-Dump in effiziente Datenstrukturen zur Analyse umwandelt, kombiniert mit mehreren anderen Tools, die mit den vorstrukturierten Daten arbeiten.

Roland Illig
quelle
Sind Sie sicher, dass der Speicherauszug nicht beschädigt ist und Sie eine neuere Version der DTFJ-JARs verwenden? Die ArrayIndexOutOfBoundsExceptionFunktionen in mindestens zwei Bugs . Ich sage dies, weil Sie beim Ausführen von MAT, das einen anderen Fix hat, kein OOME gemeldet haben .
Vineet Reynolds
jhat verwendet heapMap zum Speichern der gelesenen Objekte, die exponentiell mit der Anzahl der im Heap gespeicherten Objekte wächst. Eine Möglichkeit besteht darin, die Deklarationen von heapMap in TreeMap zu ändern und die Heap-Größe von jhat mindestens so groß wie Ihr Prozess auszuführen.
CodeDr

Antworten:

79

Normalerweise ist das, was ich verwende, ParseHeapDump.shin Eclipse Memory Analyzer enthalten und hier beschrieben , und das mache ich auf einem unserer besser ausgebauten Server (Download und Kopieren über die Linux-ZIP-Distribution, dort entpacken). Das Shell-Skript benötigt weniger Ressourcen als das Parsen des Heapspeichers über die GUI. Außerdem können Sie es auf Ihrem bulligen Server mit mehr Ressourcen ausführen (Sie können mehr Ressourcen zuweisen, indem Sie beispielsweise -vmargs -Xmx40g -XX:-UseGCOverheadLimitam Ende der letzten Zeile des Skripts etwas hinzufügen . Die letzte Zeile dieser Datei könnte nach der Änderung so aussehen

./MemoryAnalyzer -consolelog -application org.eclipse.mat.api.parse "$@" -vmargs -Xmx40g -XX:-UseGCOverheadLimit

Führen Sie es wie ./path/to/ParseHeapDump.sh ../today_heap_dump/jvm.hprof

Danach wird eine Reihe von "Index" -Dateien neben der .hprof-Datei erstellt.

Nachdem ich die Indizes erstellt habe, versuche ich, daraus Berichte zu generieren und diese Berichte an meine lokalen Computer zu senden und zu prüfen, ob ich den Schuldigen nur dadurch finden kann (nicht nur die Berichte, nicht die Indizes). Hier ist ein Tutorial zum Erstellen der Berichte .

Beispielbericht:

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

Weitere Berichtsoptionen:

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

Wenn diese Berichte nicht ausreichen und ich noch etwas graben muss (z. B. über oql), scp ich die Indizes sowie die hprof-Datei auf meinem lokalen Computer und öffne dann den Heap-Dump (mit den Indizes im selben Verzeichnis wie) der Heap Dump) mit meiner Eclipse MAT GUI. Von dort benötigt es nicht zu viel Speicher, um ausgeführt zu werden.

EDIT: Ich wollte nur zwei Notizen hinzufügen:

  • Soweit ich weiß, ist nur die Generierung der Indizes der speicherintensive Teil von Eclipse MAT. Nachdem Sie die Indizes haben, würde der größte Teil Ihrer Verarbeitung von Eclipse MAT nicht so viel Speicher benötigen.
  • Wenn ich dies in einem Shell-Skript mache, kann ich es auf einem Headless-Server machen (und normalerweise auch auf einem Headless-Server, weil sie normalerweise die leistungsstärksten sind). Und wenn Sie einen Server haben, der einen Heap-Dump dieser Größe generieren kann, haben Sie wahrscheinlich einen anderen Server, der auch so viel von einem Heap-Dump verarbeiten kann.
Franz See
quelle
4
Wichtiger Hinweis: WirdParseHeapDump.sh nur mit der Linux-Version gepackt
Christopher
Wenn ich dies versuche (ssh'd, um auf eine Linux-Box zu schlagen), schlägt es sofort mit "GTK + kann nicht initialisiert werden" fehl. Es sieht also so aus, als ob (die aktuelle Version, 15.04.2016) immer noch denkt, dass es sich um eine Benutzeroberfläche handelt (?).
Charles Roth
2
Hmm, die neueren Versionen von ParseHeapDump.sh möchten ./MemoryAnalyzer direkt ausführen. Ich experimentiere damit, den Launcher direkt mit Java auszuführen, soweit dies zu funktionieren scheint, z. B. Java -Xmx16g -Xms16g -jar plugins / org.eclipse.equinox.launcher_1.3.100.v20150511-1540.jar -consoleLog -consolelog -application org.eclipse.mat.api.parse "$ @"
Charles Roth
Anscheinend können Sie es unter OS X verwenden, indem Sie sowohl die Linux- als auch die OSX-Version herunterladen und dann ParseHeapDump.sh in dasselbe Verzeichnis wie Ihre MemoryAnalyze-Datei (in meinem Fall ~ / Downloads / mat.app / Contents / MacOS) kopieren und ändern lass es dort laufen. Oder führen Sie es natürlich auf einem Remote-Server über SSH aus :)
Rogerdpack
Es wurde ein 2-GB-Heap-Dump mit der Eclipse Memory Analyzer-Benutzeroberfläche mit nicht mehr als 500 MB Speicher geöffnet. Indexdateien wurden im laufenden Betrieb beim Öffnen der Datei erstellt (ca. 30 Sekunden). Vielleicht haben sie das Tool verbessert. Es ist praktischer als große Dateien hin und her zu kopieren, wenn es wirklich so funktioniert. Ein geringer Speicherbedarf auch ohne Konsolendienstprogramme ist für mich ein großes Plus. Aber um ehrlich zu sein, habe ich es nicht mit wirklich großen Dumps (50+ GB) versucht . Sehr interessant, wie viel Speicher benötigt wird, um so große Speicherauszüge mit diesem Tool zu öffnen und zu analysieren.
Ruslan Stelmachenko
6

Die akzeptierte Antwort auf diese verwandte Frage sollte einen guten Start für Sie bieten (verwendet Live-JMAP-Histogramme anstelle von Heap-Dumps):

Methode zum Auffinden eines Speicherverlusts in großen Java-Heap-Dumps

Die meisten anderen Heap-Analysatoren (ich verwende IBM http://www.alphaworks.ibm.com/tech/heapanalyzer ) benötigen mindestens einen Prozentsatz RAM mehr als der Heap, wenn Sie ein nettes GUI-Tool erwarten.

Abgesehen davon verwenden viele Entwickler alternative Ansätze wie die Live-Stack-Analyse, um eine Vorstellung davon zu bekommen, was los ist.

Obwohl ich mich fragen muss, warum deine Haufen so groß sind? Die Auswirkungen auf die Zuordnung und Speicherbereinigung müssen massiv sein. Ich wette, ein großer Prozentsatz dessen, was sich in Ihrem Heap befindet, sollte tatsächlich in einer Datenbank / einem dauerhaften Cache usw. usw. gespeichert werden.

Michael
quelle
5

Ich schlage vor, YourKit auszuprobieren. Normalerweise benötigt es etwas weniger Speicher als die Größe des Heap-Dumps (es indiziert es und verwendet diese Informationen, um das abzurufen, was Sie möchten).

Peter Lawrey
quelle
4

Noch ein paar Optionen:

Diese Person http://blog.ragozin.info/2015/02/programatic-heapdump-analysis.html

hat einen benutzerdefinierten Netbeans-Heap-Analysator geschrieben, der lediglich eine Schnittstelle im "Abfragestil" über die Heap-Dump-Datei verfügbar macht, anstatt die Datei tatsächlich in den Speicher zu laden.

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

Obwohl ich nicht weiß, ob "seine Abfragesprache" besser ist als die Eclipse-OQL, die in der hier akzeptierten Antwort erwähnt wird.

JProfiler 8.1 ($ 499 für Benutzerlizenz) auch die ohne große Haufen zu durchqueren können , viel Geld mit.

Rogerdpack
quelle
Funktioniert tatsächlich auf einem großen Dump, im Gegensatz zu github.com/on-site/fasthat . Nett!
Jesse Glick
4

Erster Schritt: Erhöhen Sie die RAM-Größe, die Sie MAT zuweisen. Standardmäßig ist es nicht sehr viel und es können keine großen Dateien geöffnet werden.

Wenn Sie MAT unter MAC (OSX) verwenden, haben Sie die Datei MemoryAnalyzer.ini in MemoryAnalyzer.app/Contents/MacOS. Es hat bei mir nicht funktioniert, Anpassungen an dieser Datei vorzunehmen und sie "nehmen" zu lassen. Sie können stattdessen ein modifiziertes Startbefehls- / Shell-Skript basierend auf dem Inhalt dieser Datei erstellen und von diesem Verzeichnis aus ausführen. In meinem Fall wollte ich 20 GB Heap:

./MemoryAnalyzer -vmargs -Xmx20g --XX:-UseGCOverheadLimit ... other params desired

Führen Sie diesen Befehl / dieses Skript einfach über das Terminal im Verzeichnis Inhalt / MacOS aus, um die GUI mit mehr verfügbarem RAM zu starten.

Michael Shvets
quelle
Vielen Dank. DLd das Dienstprogramm heute. Versucht mit 2x-Klick ausgeführt und es gab einen Fehler. Schaute auf Protokoll, konnte keine Datendatei erstellen und sagte, einen Schalter zu verwenden. Öffnete das .app-Paket und fand MemoryAnalyzer.ini im Ordner Eclipse \, nicht \ MacOS. Ah-ha! Also habe ich alle Dateien lokal extrahiert und getan, was Sie vorgeschlagen haben. Ich habe eine .sh-Datei in \ MacOS erstellt und die Befehle in Eclipse \ MemoryAnalyzer.ini als flache einzelne Zeile in diese Datei verschoben. Gespeicherte Datei. Lief die .sh-Datei von MacOS \ über die Befehlszeile und voila, es funktionierte.
Matt Campbell
2

Ein nicht so bekanntes Tool - http://dr-brenschede.de/bheapsampler/ - eignet sich gut für große Haufen. Es funktioniert durch Sampling, so dass es nicht die ganze Sache lesen muss, obwohl es ein bisschen pingelig ist.

Ashwin Jayaprakash
quelle
Leider heißt es "häufiges Problem: Nicht genügend Speicher: Erhöhen Sie -Xmx auf 2/3 der Speicherauszugsgröße", aber ich nehme an, wenn Sie über genügend RAM verfügen oder es auf einem Server mit genügend RAM ausführen können, könnte dies ausreichen, danke !
Rogerdpack
2

Der neueste Snapshot-Build von Eclipse Memory Analyzer bietet die Möglichkeit, einen bestimmten Prozentsatz von Objekten zufällig zu verwerfen, um den Speicherverbrauch zu reduzieren und die Analyse der verbleibenden Objekte zu ermöglichen. Lesen Sie Bug 563960 und den nächtlichen Snapshot-Build , um diese Funktion zu testen, bevor sie in der nächsten Version von MAT enthalten ist.

user13762112
quelle
1

Dies ist keine Befehlszeilenlösung, aber ich mag die Tools:

Kopieren Sie den Heap-Dump auf einen Server, der groß genug ist, um ihn zu hosten. Es ist sehr gut möglich, dass der ursprüngliche Server verwendet werden kann.

Geben Sie den Server über ein ssh -X, um das grafische Tool remote auszuführen, und verwenden Sie es jvisualvmaus dem Java-Binärverzeichnis, um das zu laden.hprof Datei des Heap-Dumps .

Das Tool lädt nicht den gesamten Heap-Dump auf einmal in den Speicher, sondern lädt Teile, wenn sie benötigt werden. Wenn Sie sich in der Datei ausreichend umschauen, erreicht der erforderliche Speicher natürlich endlich die Größe des Heap-Dumps.

kap
quelle
0

Versuchen Sie es mit jprofiler, es funktioniert gut bei der Analyse großer .hprof. Ich habe es mit einer Dateigröße von etwa 22 GB versucht.

https://www.ej-technologies.com/products/jprofiler/overview.html
Selvam M.
quelle
0

Ich bin auf ein interessantes Tool namens JXray gestoßen. Es bietet eine eingeschränkte Testlizenz für die Evaluierung. Fand es sehr nützlich, Speicherlecks zu finden. Sie können es versuchen.

Sankar Natarajan
quelle