Mit VisualVM durch den Speicher wühlen: Heap Dump
2 Kommentar(e). Veröffentlicht von Christian Ullenboom am Dienstag, Mai 26, 2009.VisualVM ist eine grafische Oberfläche mit einfachen Profiling-Möglichkeiten und einer grafischen Oberfläche etwa für das JDK-Tool jstack. VisualVM ist Teil von Java 6 (dort heißt es Java VisualVM), aber eine aktuelle Version findet sich immer unter https://visualvm.dev.java.net/; diese Version heißt dann einfach VisualVM. Nutzen wir die Version von der Webseite im Folgenden.
VisualVM wird als Zip-Archiv (etwa visualvm_111.zip) angeboten. Nach dem Auspacken befindet sich unter dem bin-Ordner das ausführbare Programm visualvm.exe, das wir starten können. (VisualVM lässt sich über ein Plugin auch über Eclipse, NetBeans oder IntelliJ einbinden.) Beim ersten Mal müssen wir noch die Lizenzen abnicken und eine Kalibrierung starten, doch dann öffnet sich schon die grafische Oberfläche. Wählen wir links im Baum Local > VisualVM aus, so schauen wir uns die Zustände, etwa den Speicherbedarf und Thread-Auslastung des Programms VisualVM selbst an.
Durch den Speicher wühlen: Heap Dump
Eine großartige Möglichkeit von VisualVM ist, sich während der Laufzeit zu einem Programm zu verbinden, und über die Objektverweise zu navigieren. Beispiel soll ein kleines Programm HeapUser sein, von dem wir später die vier Objektvariablen untersuchen wollen.
HeapUser.java
import java.util.*;
public class HeapUser
{
String string = "Hallo Welt";
Date date = new Date();
ArrayList<String> list = new ArrayList<String>( Arrays.asList( string, date.toString() ) );
HeapUser heapUser;
public static void main( String[] args )
{
HeapUser h = new HeapUser();
h.heapUser = h;
new Scanner( System.in ).next();
System.out.println( h.string );
}
}
Starten wir das Programm und VisualVM läuft noch im Hintergrund, so erkennt VisualVM automatisch das gestartete Program und aktualisiert die Baumansicht unter local.
Im Kontextmenü auf HeapUser lässt sich der HeapDump erfragen.
Nach dem Aktivieren des Schalters Classes sind alle geladenen Klassen aufgeführt, und wie viele Exemplare es von den Klassen gibt.
Unten gibt es ein Suchfeld, in dem wir HeapUser eintragen. Es bleibt eine Klasse in der Liste.
Im Kontextmenü lässt sich nun Show in Instances View aufrufen.
Die folgende Ansicht bildet den Ausgangspunkt für exploratives Arbeiten.
Links ist abgebildet die Instanz, die wir untersuchen. Das ist HeapUser, von dem es genau ein Exemplar gibt (#1). Rechts gibt es zwei Einteilungen. In der oberen Einteilung können wir die Objekteigenschaften vom links ausgewählten Objekt sehen und durch die Baumansicht tiefer reinzoomen. So enthält this, also das ausgewählte Objekt, die Variablen heapUser, list, date und string. An den auf sich selbst verweisenden Pfeilen an heapUser lässt sich – die Symbolen werden in einer Art Statusleiste kurz erklärt – erkennen, dass die Variable heapUser das eigene Objekt referenziert. Falten wir list auf, so sehen wie die Objektvariablen der ArrayList-Instanz im Baum, und unter anderem lässt sich die size ablesen, also die Anzahl Elemente in der Liste. elementData wiederum ist ein Knoten, der sich auffalten lässt, der er repräsentiert das interne Feld – die eckigen Klammern deuten den Typ „Feld“ an – der ArrayList. Wird er ausgefaltet, gelangen wir zu den beiden Strings. Im unteren Bereich der Einteilung, bei References, ist abzulesen, wer das selektierte Objekt referenziert. Es gibt zwei Stellen, an denen das untersuchte HeapUser-Objekt referenziert wird: Einmal über die lokale Variable in der main-Methode, und einmal über die Objektvariable.
Profiling von Java-Applikationen
Ein Profiler zeigt an, an welchen Stellen ein Programm Prozessorzeit verbraucht. Auf der Webseite https://visualvm.dev.java.net/profiler.html stellt Sun Dokumentation bereit, wie VisualVM als Profiler genutzt wird.
Labels: Insel

Finde zwar VisualVM toll, aber für Heaps zu betrachten ist Memory Analyzer (MAT) noch besser. Alleine die Möglichkeit eine "retained size" zu berechnen hilft enorm bei der Suche nach zu großen Objekten im Heap.
Wenn es nur auch bei PermGen-Problemen so einfach wäre :-)
Hallo!
Wollte gerade etwas mit VisualVM herumspielen, leider zeigt es aber meine Netbeans RCP Applications als "Unknown Application (pid XXXX)" an und ich kann keinen Heapdump machen....
OS ist Vista, Java 6 Upd. 13, Netbeans 6.5
Hat jemand eine Lösung? Danke im Voraus!