Bei der Entwicklung von Java-Software kann es vorkommen, dass je nach Umfang und Komplexität der Software viel Speicher zur Ausführungszeit gebraucht wird. In diesem Fall kann es nun früher oder später zu der Java-Exception java.lang.OutOfMemoryError kommen. Die Hauptursachen dieser Exception können sein:

  • Es wird mehr Speicher gebraucht als dem ausführendem Programm zugeordnet sind
  • Alte ungenutzte Objekte werden nicht abgeräumt und belegen den Java-Heap (Programmierfehler)

Im ersten Fall ist die einzige Lösung des Problems das Erhöhen des zugesicherten Arbeitsspeichers. Dies geht mit folgendem Zusatz beim Programmaufruf:

JAVA_OPTS="-Xms256m -Xmx512m"

Die zweite Möglichkeit benötigt ein wenig mehr Analyseaufwand.

Java Heap Profiler

Um analysieren zu können, welche Daten sich im Java Heap Space befinden, müssen Sie nicht unbedingt teure Profiling-Tools kaufen. Eine Speicheranalyse ist bereits mit Bordmitteln des JDK möglich. Im bin-Verzeichnis des installierten JDK befindet sich die notwendigen Tool jps, jmap und jhat. Diese dienen zum Erstellen einer Karte des Speichers, welche im späteren Verlauf analysiert werden kann.

jps Prozess-ID

Mittels dem Befehl jps können Sie die Prozess-IDs aller Java-Prozesse auflisten lassen. Sollten Sie viele Java Prozesse parallel laufen haben, von denen Sie nur einen bestimmten analysieren möchten, ist es ratsam mittels grep die Prozess-ID mit dem Pfad des laufenden Prozesses abzugleichen, um nicht ein falsches Speicherabbild zu erzeugen.

jmap Speicherabbild erzeugen

Die zuvor angesprochene Speicherkarte wird mittels dem Befehl jmap erstellt. Die oben ermittelte ID müssen Sie in folgende Befehlszeile einfügen (eckige Klammern auch entfernen):

jmap -dump:format=b,file=dump_001.dat [ID]

Es wird ein binärer Dump des Java-Heaps erstellt. Das Speichern des Speicherabbild kann je nach Speicher auch mal eine Minute oder länger zum Speichern brauchen.

jhat Analyse starten

Die JDK Bordmittel haben keine bedeutende Benutzeroberfläche mit vielen Funktionen und Optionen, sondern liefern hier lediglich einen kleinen Webserver aus, welcher die zu analysierenden Daten im Browser anzeigen lässt. Um den Webserver zu starten, führen Sie folgenden Befehl aus:

jhat -J-Xmx512m dump_001.dat

Erreichbar ist die Benutzeroberfäche für die Analyse unter folgender Adresse: http://localhost:7000

Java Heap

Java Heap analysieren

Wenn Sie im Browser die Adresse http://localhost:7000 aufgerufen haben, bekommen Sie eine Übersicht aller Klassen im Speicher. Wenn Sie an das Ende der Seite scrollen finden Sie Optionen zur Datenanzeige.

Über den Link “Show instance count for all classes” können Sie sich die Anzahl Instanzen pro Klasse anzeigen lassen. Sie können in der Liste auf die Anzahl Instanzen klicken und sich alle Instanzen auflisten lassen. Weiterhin lässt sich jede Instanz einzeln mit allen Details nach einem weiteren Klick anzeigen. Hier ist die Information der Referenzen hilfreich um zu sehen, welche anderen Objekte noch auf dieses Objekt verweisen. Anhand der Referenzen können Sie sehen, an welcher Stelle evtl. nicht korrekt abgeräumt wurde.

Es werden hier nicht die Variablennamen genannt, sondern die Objektnummern. Diese sind analog mit den den Eclipse-Debugger Objektnummern zu vergleichen.

Fazit

Das JDK Bordmittel zum Profilen des Java-Heaps ist nicht das Beste. Sie können Sie hier zwar Anzahl von Instanzen und Refenzen auflisten lassen, jedoch finden Sie hier keinen Hinweis auf Programmierfehler. Sie können nur einschränken, welche Klassen und Objekte am hohen Speicherverbrauch schuld sein können. Mehr Informationen hierzu gibt es auch im Oracle-Blog.

Java Heap analysieren
Markiert in: