Erläuterungen zur HPROF-Ausgabedatei

Im ersten Abschnitt der Datei stehen allgemeine Kopfzeileninformationen wie eine Erklärung der Optionen, das Copyright und Haftungsausschlüsse. Es folgt eine Zusammenfassung der einzelnen Threads.

Sie können die Ausgabe sehen, nachdem Sie HPROF mit einem einfachen Programm (wie im Folgenden gezeigt) verwendet haben. Das folgende Testprogramm erstellt zwei Threads und führt sie für eine kurze Zeit aus. Der Ausgabe können Sie entnehmen, dass die beiden Threads mit den Namen apples und oranges nach dem systemgenerierten Thread main erstellt wurden. Beide Threads werden vor dem Thread main beendet. Für jeden Thread werden die Adresse, die ID, der Name und der Threadgruppenname angezeigt. Sie können sehen, in welcher Reihenfolge Threads gestartet und beendet werden.

THREAD START (obj=11199050, id = 1, name="Signal dispatcher", group="system")
THREAD START (obj=111a2120, id = 2, name="Reference Handler", group="system")
THREAD START (obj=111ad910, id = 3, name="Finalizer", group="system")
THREAD START (obj=8b87a0, id = 4, name="main", group="main")
THREAD END (id = 4)
THREAD START (obj=11262d18, id = 5, name="Thread-0", group="main")
THREAD START (obj=112e9250, id = 6, name="apples", group="main")
THREAD START (obj=112e9998, id = 7, name="oranges", group="main")
THREAD END (id = 6)
THREAD END (id = 7)
THREAD END (id = 5)

Der Traceausgabeabschnitt enthält normale Stack-Trace-Informationen. Die Tiefe jedes Trace kann festgelegt werden und jeder Trace hat eine eindeutige ID:

TRACE 5:
	java/util/Locale.toLowerCase(Locale.java:1188)
	java/util/Locale.convertOldISOCodes(Locale.java:1226)
	java/util/Locale.<init>(Locale.java:273)
	java/util/Locale.<clinit>(Locale.java:200)

Ein Trace enthält eine Anzahl Frames und jeder Frame enthält den Klassennamen, Methodennamen, Dateinamen und die Zeilennummer. Im vorhergehenden Beispiel können Sie sehen, dass Zeilennummer 1188 der Datei Locale.java (die sich in der Methode toLowerCase befindet) von der Funktion convertOldISOCodes() in derselben Klasse aufgerufen wurde. Diese Traces sind bei der Verfolgung des Ausführungspfads Ihres Programms hilfreich. Wenn Sie die Option 'monitor' angeben, wird ein Monitorspeicherauszug erstellt, der dem folgenden Beispiel ähnlich ist:

MONITOR DUMP BEGIN
    THREAD 8, trace 1, status: R
    THREAD 4, trace 5, status: CW
    THREAD 2, trace 6, status: CW
    THREAD 1, trace 1, status: R
    MONITOR java/lang/ref/Reference$Lock(811bd50) unowned
	waiting to be notified: thread 2
    MONITOR java/lang/ref/ReferenceQueue$Lock(8134710) unowned
	waiting to be notified: thread 4
    RAW MONITOR "_hprof_dump_lock"(0x806d7d0)
	owner: thread 8, entry count: 1
    RAW MONITOR "Monitor Cache lock"(0x8058c50)
	owner: thread 8, entry count: 1
    RAW MONITOR "Monitor Registry lock"(0x8058d10)
	owner: thread 8, entry count: 1
    RAW MONITOR "Thread queue lock"(0x8058bc8)
	owner: thread 8, entry count: 1
MONITOR DUMP END
MONITOR TIME BEGIN (total = 0 ms) Thu Aug 29 16:41:59 2002
MONITOR TIME END
Der erste Teil des Monitorspeicherauszugs enthält eine Liste von Threads, einschließlich des Traceeintrags, der den vom Thread ausgeführten Code angibt. Außerdem wird für jeden Thread ein Threadstatus angegeben:
  • R — Runnable (Der Thread kann ausgeführt werden, wenn er die Möglichkeit dazu erhält)
  • S — Suspended (Der Thread wurde von einem anderen Thread ausgesetzt)
  • CW — Condition Wait (Der Thread befindet sich im Wartestatus)
  • MW — Monitor Wait (Der Monitor befindet sich im Wartestatus)
Als Nächstes folgt eine Liste von Monitoren mit Angabe ihrer Eigner und einer Information darüber, ob irgendwelche Threads auf sie warten.

Der nächste Abschnitt ist der Heapspeicherauszug. Er enthält eine Liste der verschiedenen Speicherbereiche und zeigt an, wie sie zugeordnet sind:

CLS 1123edb0 (name=java/lang/StringBuffer, trace=1318)
	super		111504e8
	constant[25]	8abd48
	constant[32]	1123edb0
	constant[33]	111504e8
	constant[34]	8aad38
	constant[115]	1118cdc8
CLS 111ecff8 (name=java/util/Locale, trace=1130)
	super		111504e8
	constant[2]	1117a5b0
	constant[17]	1124d600
	constant[24]	111fc338
	constant[26]	8abd48
	constant[30]	111fc2d0
	constant[34]	111fc3a0
	constant[59]	111ecff8
	constant[74]	111504e8
	constant[102]	1124d668
	...
CLS 111504e8 (name=java/lang/Object, trace=1)
	constant[18]	111504e8

CLS informiert Sie darüber, dass Speicher für eine Klasse zugeordnet wird. Die danach folgende Hexadezimalzahl ist die Adresse, an der der Speicher zugeordnet wird.

Als Nächstes folgen der Klassenname und eine Tracereferenz. Verwenden Sie diese Informationen als Querverweis auf die Traceausgabe und schauen Sie dort nach, wann die Klasse aufgerufen wird. Anhand des Verweises können Sie in dem betreffenden Trace die Zeilennummer der Anweisung ermitteln, die zur Erstellung dieses Objekts geführt hat. Die Adressen der Konstanten in dieser Klasse werden ebenso angezeigt wie, im vorherigen Beispiel, die Adresse der Klassendefinition für die Superklasse. Beide Klassen sind untergeordnete Objekte derselben Superklasse (mit der Adresse 11504e8). Im weiteren Verlauf der Ausgabe finden Sie die Definition und den Namen dieser Klasse. Es handelt sich um die Klasse 'Object' (eine Klasse, von der jede Klasse etwas erbt). Die JVM lädt die gesamte Superklassenhierarchie, bevor sie eine Unterklasse verwenden kann. Deshalb sind immer für alle Superklassen Klassendefinitionen vorhanden. Es gibt auch Einträge für Objekte (OBJ) und Arrays (ARR):

OBJ 111a9e78 (sz=60, trace=1, class=java/lang/Thread@8b0c38)
	name		111afbf8
	group		111af978
	contextClassLoader	1128fa50
	inheritedAccessControlContext	111aa2f0
	threadLocals	111bea08
	inheritableThreadLocals	111bea08
ARR 8bb978 (sz=4, trace=2, nelems=0, elem type=java/io/ObjectStreamField@8bac80)

Wenn Sie die Option heap auf sites oder all setzen, erhalten Sie eine Liste der einzelnen Speicherbereiche, die Ihrem Code zugeordnet sind. Der Parameter all kombiniert dump und sites. Die Liste ist so sortiert, dass die Sites mit den größten Speicherzuordnungen am Anfang stehen:

SITES BEGIN (ordered by live bytes) Tue Feb 06 10:54:46 2007
          percent          live          alloc'ed  stack class
 rank   self  accum     bytes objs     bytes  objs trace name
    1 20.36% 20.36%    190060   16    190060    16 300000 byte[]
    2 14.92% 35.28%    139260 1059    139260  1059 300000 char[]
    3  5.27% 40.56%     49192   15     49192    15 300055 byte[]
    4  5.26% 45.82%     49112   14     49112    14 300066 byte[]
    5  4.32% 50.14%     40308 1226     40308  1226 300000 java.lang.String
    6  1.62% 51.75%     15092  438     15092   438 300000 java.util.HashMap$Entry
    7  0.79% 52.55%      7392   14      7392    14 300065 byte[]
    8  0.47% 53.01%      4360   16      4360    16 300016 char[]
    9  0.47% 53.48%      4352   34      4352    34 300032 char[]
   10  0.43% 53.90%      3968   32      3968    32 300028 char[]
   11  0.40% 54.30%      3716    8      3716     8 300000 java.util.HashMap$Entry[]
   12  0.40% 54.70%      3708   11      3708    11 300000 int[]
   13  0.31% 55.01%      2860   16      2860    16 300000 java.lang.Object[]
   14  0.28% 55.29%      2644   65      2644    65 300000 java.util.Hashtable$Entry
   15  0.28% 55.57%      2640   15      2640    15 300069 char[]
   16  0.27% 55.84%      2476   17      2476    17 300000 java.util.Hashtable$Entry[]
   17  0.25% 56.08%      2312   16      2312    16 300013 char[]
   18  0.25% 56.33%      2312   16      2312    16 300015 char[]
   19  0.24% 56.57%      2224   10      2224    10 300000 java.lang.Class

In diesem Beispiel sind 5,27 % des insgesamt zugeordneten Speichers dem Trace 300055 zugeordnet. Aus dem Prozentsatz ergibt sich eine Größe von 49192 Byte.

Die Option cpu liefert Profilerstellungsinformationen über den Prozessor. Wenn cpu auf 'samples' gesetzt wird, enthält die Ausgabe die Ergebnisse regelmäßiger Stichproben, die während der Ausführung des Codes erhoben werden. Für jede Stichprobe wird der verarbeitete Codepfad aufgezeichnet und ein Bericht wie der folgende erstellt:

CPU SAMPLES BEGIN (total = 714) Fri Aug 30 15:37:16 2002
rank   self  accum   count trace method
1 76.28% 76.28% 501 77 MyThread2.bigMethod
2 6.92% 83.20% 47 75 MyThread2.smallMethod
...
CPU SAMPLES END

Sie können sehen, dass die Methode bigMethod() 76,28 % der Ausführungszeit des Prozessors beansprucht hat und bei 714 Stichproben 501 Mal ausgeführt wurde. Anhand der Trace-ID können Sie die genaue Route ermitteln, die zum Aufruf dieser Methode geführt hat.