「Java」スレッドダンプを取得する

スレッドダンプの取得を調べてみたので、その時のメモ。

やり方としては、スレッドダンプを取得する対象の Java プロセスに対して
1. jstack < pid >
2. kill -3 < pid >
すると取得できるみたいです。

・jstack - スタックトレース
http://docs.oracle.com/javase/jp/7/technotes/tools/share/jstack.html

※ < pid > は jps コマンド等で調べてやります。

jps - Java 仮想マシンプロセスステータスツール
http://docs.oracle.com/javase/jp/7/technotes/tools/share/jps.html

※ 今回は確認してませんが、他の方法としては VisualVM や JConsole でもできる感じですかね ( JConsole はスレッドの情報が見れるって感じかな )。

Java VisualVM
http://docs.oracle.com/javase/jp/7/technotes/guides/visualvm/threads.html
・JConsole の使用 - Java SE 監視および管理ガイド
http://docs.oracle.com/javase/jp/7/technotes/guides/management/jconsole.html


以下のような Java のコード用意しました。
■ JstackTest.java

package test;

public class JstackTest {
	public static void main(String[] args) {
		Test1 t1 = new Test1();
		t1.setName("t1");
		
		Test2 t2 = new Test2();
		t2.setName("t2");
		
		t1.start();
		t2.start();
	}
}

class Test1 extends Thread {
	public void run() {
		try {
			System.out.println("test1 start");
			sleep(30000);
			System.out.println("test1 end");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

class Test2 extends Thread {
	public void run() {
		try {
			System.out.println("test2 start");
			sleep(30000);
			System.out.println("test2 end");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

※ 後でわかりやすいように、スレッドに "t1"、"t2" と名前をつけてやってます。

・Thread (Java Platform SE 7 )
http://docs.oracle.com/javase/jp/7/api/java/lang/Thread.html

上記を実行して jstack コマンド等を発行すると、以下のようなスレッドダンプが取得できる。

2014-03-04 01:02:20
Full thread dump Java HotSpot(TM) Client VM (24.51-b03 mixed mode):

"Attach Listener" daemon prio=10 tid=0xb7676800 nid=0x886 waiting on condition [0x00000000]
   java.lang.Thread.State: RUNNABLE

"DestroyJavaVM" prio=10 tid=0xb7606800 nid=0x869 waiting on condition [0x00000000]
   java.lang.Thread.State: RUNNABLE

"t2" prio=10 tid=0xb7675000 nid=0x872 waiting on condition [0xa0b78000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
	at java.lang.Thread.sleep(Native Method)
	at test.Test2.run(JstackTest.java:32)

"t1" prio=10 tid=0xb7674000 nid=0x871 waiting on condition [0xa0bc9000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
	at java.lang.Thread.sleep(Native Method)
	at test.Test1.run(JstackTest.java:20)

"Service Thread" daemon prio=10 tid=0xb766dc00 nid=0x86f runnable [0x00000000]
   java.lang.Thread.State: RUNNABLE

"C1 CompilerThread0" daemon prio=10 tid=0xb766bc00 nid=0x86e waiting on condition [0x00000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" daemon prio=10 tid=0xb766a000 nid=0x86d runnable [0x00000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" daemon prio=10 tid=0xb765a800 nid=0x86c in Object.wait() [0xa10ad000]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait(Native Method)
	- waiting on <0xa1605460> (a java.lang.ref.ReferenceQueue$Lock)
	at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)
	- locked <0xa1605460> (a java.lang.ref.ReferenceQueue$Lock)
	at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151)
	at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:189)

"Reference Handler" daemon prio=10 tid=0xb7658000 nid=0x86b in Object.wait() [0xa10fe000]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait(Native Method)
	- waiting on <0xa1605038> (a java.lang.ref.Reference$Lock)
	at java.lang.Object.wait(Object.java:503)
	at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)
	- locked <0xa1605038> (a java.lang.ref.Reference$Lock)

"VM Thread" prio=10 tid=0xb7656800 nid=0x86a runnable 

"VM Periodic Task Thread" prio=10 tid=0xb7670000 nid=0x870 waiting on condition 

JNI global references: 109

デフォルトでいろいろとスレッドが生成されるみたいですが、ちゃんと Java コードで生成した "t1"、"t2" スレッドの情報が取得できてますね ( sleep しているので Thread.State は "TIMED_WAITING" です )。

・Thread.State (Java Platform SE 7 )
http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.State.html#TIMED_WAITING


駆け足でしたが、以上です。

< 環境情報 >
CentOS 6.2
Java SE 7 Update 51