JDK1.4.2_12で"-XX:+HeapDumpOnOutOfMemoryError"を試す
こんなトイプロ作成.
import java.util.List; import java.util.ArrayList; public class Test { public static void main(String[] args) { Test test = new Test(); test.doit(); } private void doit() { List list = new ArrayList(); for (;;) { list.add(new byte[1024]); } } }
こんなオプション付けて実行.しばらくするとOutOfMemoryErrorで落ちる.
> java -Xms256m -Xmx256m -XX:+HeapDumpOnOutOfMemoryError Test java.lang.OutOfMemoryError: Java heap space Dumping heap to java_pid5380.hprof ... Heap dump file created [264751615 bytes in 49.285 secs] java.lang.OutOfMemoryError Exception in thread "main"
この「java_pidjvmid.hprof」ってのがダンプファイル.当たり前だが,ファイルサイズは,そんときのヒープサイズ分あるので,「-Xmx/-Xms」オプションの値によっては二次災害(ディスクの空きが無くなる)を起こしそうな予感.
#ダンプファイルの出力先は指定できないのかな?
ダンプファイルの解析は,HATで行う.使い方は,以下のようにしてHATにダンプファイルを食わせるだけ.
ダンプファイルがデカイとHATにもそれなりのヒープを割り当てないといけないので,案外実用に耐えないんじゃないかと思う.
> hat java_pid5380.hprof Started HTTP server on port 7000 Reading from d:?temp?memoryTest?java_pid5380.hpr Dump file created Mon Jun 19 13:59:43 JST 2006 Snapshot read, resolving... Resolving 257767 objects... Chasing references, expect 515 dots............. ................................................ ................... Eliminating duplicate references................ ................................................ .................. Snapshot resolved. Server is ready.
HATはHTTPサーバ付きのWebアプリのようなので、立ち上がったら「http://localhost:7800/」にアクセスする(HATって昔から,こんなツールだったっけ?).
正直言ってHATのUIはよくわからない.YourKit 5.5から,ダンプファイルのインポートが可能になったので,こっちで試す.
HATよりは使い易いが,やっぱりヒープサイズがデカイと計算に時間がかかってサクサク動いてくれない(その点ではCPUプロファイルのほうが楽だ).
うーむー,「-XX:+HeapDumpOnOutOfMemoryError」オプションは付けるべきか悩みどころだ.付けたところで,解析するにはそれなりの用意が必要だし,鰯の頭代わりにするにはディスクを食いそう.
OutOfMemoryなんぞ,本番で起きてくれるなってのが本音なので,このオプションはテストフェーズに設定して,十分な負荷テストを行うのが吉とみた.
JDK1.4.2_12のリリースノートで気になったこと
6374905 hotspot garbage_collector SurvivorRatio が -XX:+UseConcMarkSweepGC を使用すると無視される
やっぱり,そうか!!
しかし,改めてリリースノートを読むと,結構笑えない修正点が多い.
Dependency FinderのJarJarDiff
リリースノートにChangeLogだけではなく,APIレベルの変更を教えてとうるさいご要望があったので,Dependency FinderのJarJarDiff Taskを使うことにした.
JarJarDiffで生成される元データのXMLには,DOCTYPE宣言があって,これがAntのXSLTタスクの邪魔になる(ご丁寧にDTDを探しに行く)んで,REPLACEタスクでさっくり削る.
<jarjardiff destfile="${work.dir}/jarjardiff.xml" name="XXXXX" encoding="Windows-31J" oldlabel="直前のバージョン" newlabel="今回のバージョン"> <old><pathelement location="old.jar"/></old> <new><pathelement location="new.jar"/></new> </jarjardiff> <replace file="${work.dir}/jarjardiff.xml"> <replacetoken><!DOCTYPE differences SYSTEM "http://depfind.sourceforge.net/dtd/differences.dtd"></replacetoken> <replacevalue></replacevalue> </replace>
他に良い方法があったら教えてホスイ.
XSLTに喰わすスタイルシートは「DiffToHTML.xsl」.利用者に関係無いクラスの差分も出るけど,知らん顔する.:-D
面倒臭がりのテストコード
シンタックス・シュガーとは言え,多用は控えようっと.
String expect, actual; actual = HogeHoge.foo(expect = "期待値"); assertEquals(expect, actual);