macosでJVMのスレッドダンプを取得する
JVMのこと、詳しくなりたくって、でも何もできずにいる自分がただそこにいるだけで、悔しくて泣きたくて。
そんな気持ちを最近持ったので、勉強しはじめた。
とりあえずjavaをインストールする
ORACLEのインストールガイドを読むのが一番。
MacでのJavaのインストール方法
インストール完了後、こんな感じでバージョンを確認できたらよさげ。
$java -version java version "1.8.0_131" Java(TM) SE Runtime Environment (build 1.8.0_131-b11) Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
javaのプログラムを起動する
とりあえず簡単なプログラムを起動させて、立ち上がっているプロセスを確認したい。
ただ、ずっと起動しぱなっしのプロセスにしてあげる必要があるので、BufferedReader
というやつを使って、入力完了するまでプロセスが死なないようにした。
import java.io.*; public class HelloWorld { public static void main (String[] args) throws IOException { InputStreamReader is = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(is); System.out.println("何か入力してください."); String str = br.readLine(); System.out.println(str + "が入力されました."); } }
HelloWorld.java
として保存して、 javac HelloWorld.java
, java HelloWorld
を実行すると実行される。
javaプロセス起動中にスレッドダンプを取得
プログラムを実行すると、 何か入力してください.
と出たまま入力せずに別のコンソールから起動中のプロセスを確認する。
$ps aux | grep java user 34577 0.0 0.0 2432804 776 s021 S+ 2:27AM 0:00.00 grep java user 34573 0.0 0.3 6026488 22852 s019 S+ 2:27AM 0:00.16 /usr/bin/java HelloWorld
ちゃんと立ち上がったままになってて良い感じ。
次にスレッドダンプを取得。
$jps 34582 Jps 34573 HelloWorld
jps
コマンドで、pidに紐づいたjavaの実行プログラムがリストで取れるっぽい。
さらに jstack
コマンドでpidを指定するとそのプロセスのスレッドダンプを出力できる。
$jstack 34420 2017-05-17 02:13:46 Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.131-b11 mixed mode): "Attach Listener" #9 daemon prio=9 os_prio=31 tid=0x00007fc815083800 nid=0x1307 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Service Thread" #8 daemon prio=9 os_prio=31 tid=0x00007fc815025800 nid=0x4903 runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE "C1 CompilerThread2" #7 daemon prio=9 os_prio=31 tid=0x00007fc816008800 nid=0x4703 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "C2 CompilerThread1" #6 daemon prio=9 os_prio=31 tid=0x00007fc81582c800 nid=0x4503 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "C2 CompilerThread0" #5 daemon prio=9 os_prio=31 tid=0x00007fc815871800 nid=0x4303 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Signal Dispatcher" #4 daemon prio=9 os_prio=31 tid=0x00007fc815871000 nid=0x4103 runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Finalizer" #3 daemon prio=8 os_prio=31 tid=0x00007fc815857800 nid=0x3103 in Object.wait() [0x000070000dd8e000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x0000000795588ec8> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143) ...
あとはよさげに
jstack 34420 > hoge.log
とかしてあげるとよい。
なお、スレッドダンプの読み方も調べてみたけど語るには知識がなさすぎるので、参考になった記事を共有するに留めておくことにします。
Java書かないのでまったくここらへんのことわからないけど、少しずつこうやって知見を貯めていきたい。