2008年3月25日火曜日

jhatメモ

class HeapDump {
public static void main(String[] args) {
java.util.List l = new java.util.ArrayList();
for (int i = 0; ; ++i) {
l.add(i);
}
}
}


のような、OutOfMemoryErrorが発生するプログラムを実行。

$ java -XX:+HeapDumpOnOutOfMemoryError HeapDump
java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid4888.hprof ...
Heap dump file created [84987937 bytes in 4.720 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.lang.Integer.valueOf(Integer.java:585)
at HeapDump.main(HeapDump.java:9)


ダンプファイルができているのを確認。

$ ls
HeapDump.class
HeapDump.java
java_pid4888.hprof


なお、
http://java.sun.com/javase/ja/6/docs/ja/technotes/tools/share/jhat.html
によれば、

Java のヒープダンプを生成するには、いくつかの方法があります。
* jmap の -dump オプションを使って実行時にヒープダンプを取得する。
* jconsole のオプションを使って HotSpotDiagnosticMXBean 経由で実行時にヒープダンプを取得する。
* -XX:+HeapDumpOnOutOfMemoryError VM オプションを指定すると、OutOfMemoryError のスロー時にヒープダンプが生成される。
* hprof を使用する。


という事らしい。

jhatの引数にダンプファイルを指定して起動すると、

$ jhat java_pid4888.hprof 
Reading from java_pid4888.hprof...
Dump file created Tue Mar 25 14:19:26 JST 2008
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Hashtable.rehash(Hashtable.java:356)
at java.util.Hashtable.put(Hashtable.java:412)
at com.sun.tools.hat.internal.model.Snapshot.addHeapObject(Snapshot.java:153)
at com.sun.tools.hat.internal.parser.HprofReader.readInstance(HprofReader.java:724)
at com.sun.tools.hat.internal.parser.HprofReader.readHeapDump(HprofReader.java:470)
at com.sun.tools.hat.internal.parser.HprofReader.read(HprofReader.java:222)
at com.sun.tools.hat.internal.parser.Reader.readFile(Reader.java:79)
at com.sun.tools.hat.Main.main(Main.java:143)


がーん。気を取り直して。

bash-3.2$ jhat -J-Xmx512m java_pid4888.hprof 
Reading from java_pid4888.hprof...
Dump file created Tue Mar 25 14:19:26 JST 2008
Snapshot read, resolving...
Resolving 3312656 objects...
Chasing references, expect 662 dots......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
Eliminating duplicate references......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.


となった後、http://127.0.0.1:7000/ にアクセスして、Heap Histogramをみると、

Class Instance Count Total Size
class java.lang.Integer 3308797 13235188


となってて、Integerが怪しいね、って話になる。
References by Typeで辿ると、

Class Count
[Ljava.lang.Object; 3308667


ってのがあって、
Objectのでかい配列がIntegerの配列になってるんだ、って閃いて、
Collection系のインスタンスが怪しいね、って閃いて、
ArrayListじゃね?、と閃いて解決。
あってるよね?

0 件のコメント: