Serviceability Agentやjhsdbについては、OpenJDK Reviewerの末永さんのスライドが大変参考になります。
www.slideshare.net
JDK 8まで、HSDB (CLHSDB)を使うにはjava
コマンドで実行しました。
$ java -Dsun.jvm.hotspot.degugger.useProcDebugger=true -classpath $JAVA_HOME/lib/sa-jdi.jar sun.jvm.hotspot.HSDB
JDK 9からjhsdb
というランチャーが入ったので、簡単に呼び出せます。
$ jhsdb hsdb
HSDBが立ち上がりました。HSDB自体の話は今回の範囲外ですが、コアファイルを読み込ませて解析するデバッガです。
このjhsdb
は、ややこしいのですがHSDBだけのものではありません。
$ jhsdb clhsdb command line debugger debugd debug server hsdb ui debugger jstack --help to get more information jmap --help to get more information jinfo --help to get more information jsnap --help to get more information
jstackやjmapなども呼び出せます。
jhsdbはバイナリファイルですが、文字列を読んでみます。
$ strings $JAVA_HOME/bin/jhsdb JDK_JAVA_OPTIONS _JAVA_LAUNCHER_DEBUG _JAVA_OPTIONS NOTE: Picked up %s: %s 9+181 java jhsdb -J-ms8m jdk.hotspot.agent/sun.jvm.hotspot.SALauncher ...
SALauncher
というクラスを読んでいます。このSAというのはServiceability Agentの略です。ネイティブデバッガ同様の仕組みでプロセスから情報収集できる(上記スライドより)とのことです。
OpenJDKをダウンロードすると、SALauncher
クラスがあります。
... public class SALauncher { ... public static void main(String[] args) { // Provide a help if (args.length == 0) { launcherHelp(); return; } ... } ... }
main
メソッドがあります。これが呼び出されているのでしょう。先ほどjhsdb
と引数なしで実行しました。launcherHelp()
を見てみます。
private static boolean launcherHelp() { System.out.println(" clhsdb \tcommand line debugger"); System.out.println(" debugd \tdebug server"); System.out.println(" hsdb \tui debugger"); System.out.println(" jstack --help\tto get more information"); System.out.println(" jmap --help\tto get more information"); System.out.println(" jinfo --help\tto get more information"); System.out.println(" jsnap --help\tto get more information"); return false; }
まさに出力に合致するコードです。単にSystem.out.println()
しているだけなんですね。
あとは引数で指定したツールを実行するというコードでした。
// Run SA interactive mode if (args[0].equals("clhsdb")) { runCLHSDB(oldArgs); return; } if (args[0].equals("hsdb")) { runHSDB(oldArgs); return; } // Run SA tmtools mode if (args[0].equals("jstack")) { runJSTACK(oldArgs); return; } if (args[0].equals("jmap")) { runJMAP(oldArgs); return; } if (args[0].equals("jinfo")) { runJINFO(oldArgs); return; } if (args[0].equals("jsnap")) { runJSNAP(oldArgs); return; } if (args[0].equals("debugd")) { runDEBUGD(oldArgs); return; }
このモジュール内にHSDB.javaやCLHSDB.java、JSnap.javaなどがあるので、ここからツールをどれか読み進めます。