Java:スレッドダンプをとる
Last-modified: 2013-08-24 (土) 02:14:21 (3891d)
Top / Java:スレッドダンプをとる
Java:スレッドダンプをとる †
こんな状況ありませんか?
JAVAのプログラムがOutOfMemoryError?を出力していて、もしかしたらメモリリークのおそれがある、けど、どうやって特定したらよいか、方法がわからない。
そんなとき、
- 実行中のプログラムを一時停止することが可能(運用的に)
- 実行中のVMのFULLGCを実行することが可能(運用的に)
であれば、一手間かけることでJAVAVM中のスレッドダンプを出力することが出来ます。
手順 †
至って簡単です。
- javaの起動オプションに
-XX:+PrintClassHistogram
を追加する
- VMを再起動する
- 再起動したVMのプロセスに対して「SIGQUIT」シグナルを送信する
javaの起動オプションで-XX:+PrintClassHistogram?を追加することで、SUGQUITシグナルを受信した際に、VMでFullGCが強制的に実行され、JAVAのヒープ使用状況が標準出力(標準エラー出力?)に出力されます。
実験 †
あるjavaプログラムの起動オプションに上述のオプションを設定し、情報を出力した際の出力結果を以下に掲載します。(長いので、一部のみ掲載)
まず、SIGQUITシグナルを送信します。
kill -SIGQUIT <PID>
以下の出力の表部分で、どのクラスがどれくらいメモリを使用しているかわかります。
Full thread dump Java HotSpot(TM) Client VM (1.5.0_22-b03 mixed mode, sharing): "Timer-3" daemon prio=1 tid=0x084ba458 nid=0x1bcb in Object.wait() [0xb16fc000..0xb16fceb0] at java.lang.Object.wait(Native Method) - waiting on <0x89454688> (a java.util.TaskQueue) at java.util.TimerThread.mainLoop(Unknown Source) - locked <0x89454688> (a java.util.TaskQueue) at java.util.TimerThread.run(Unknown Source) "Timer-2" daemon prio=1 tid=0x084b92f0 nid=0x1bca in Object.wait() [0xb177d000..0xb177de30] at java.lang.Object.wait(Native Method) - waiting on <0x8945b128> (a java.util.TaskQueue) at java.lang.Object.wait(Unknown Source) at java.util.TimerThread.mainLoop(Unknown Source) - locked <0x8945b128> (a java.util.TaskQueue) at java.util.TimerThread.run(Unknown Source) "Timer-1" daemon prio=1 tid=0x084a3d70 nid=0x1bc9 in Object.wait() [0xb17fe000..0xb17fedb0] at java.lang.Object.wait(Native Method) - waiting on <0x8945b1a0> (a java.util.TaskQueue) at java.util.TimerThread.mainLoop(Unknown Source) - locked <0x8945b1a0> (a java.util.TaskQueue) at java.util.TimerThread.run(Unknown Source) "Timer-0" daemon prio=1 tid=0x0849bfa8 nid=0x1bc8 in Object.wait() [0xb19b7000..0xb19b8130] at java.lang.Object.wait(Native Method) - waiting on <0x89444d70> (a java.util.TaskQueue) at java.util.TimerThread.mainLoop(Unknown Source) - locked <0x89444d70> (a java.util.TaskQueue) at java.util.TimerThread.run(Unknown Source) "Low Memory Detector" daemon prio=1 tid=0x08313198 nid=0x1bc6 runnable [0x00000000..0x00000000] "CompilerThread0" daemon prio=1 tid=0x08311c40 nid=0x1bc5 waiting on condition [0x00000000..0xb25dc998] "Signal Dispatcher" daemon prio=1 tid=0x08310d70 nid=0x1bc4 waiting on condition [0x00000000..0xb265d098] "Finalizer" daemon prio=1 tid=0x0830a410 nid=0x1bc3 in Object.wait() [0xb29c9000..0xb29c9eb0] at java.lang.Object.wait(Native Method) - waiting on <0x8942b980> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(Unknown Source) - locked <0x8942b980> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(Unknown Source) at java.lang.ref.Finalizer$FinalizerThread.run(Unknown Source) "Reference Handler" daemon prio=1 tid=0x08309760 nid=0x1bc2 in Object.wait() [0xb2a4a000..0xb2a4ae30] at java.lang.Object.wait(Native Method) - waiting on <0x8942ba08> (a java.lang.ref.Reference$Lock) at java.lang.Object.wait(Unknown Source) at java.lang.ref.Reference$ReferenceHandler.run(Unknown Source) - locked <0x8942ba08> (a java.lang.ref.Reference$Lock) "main" prio=1 tid=0x082ca130 nid=0x1bbf in Object.wait() [0xbfb70000..0xbfb706e8] at java.lang.Object.wait(Native Method) - waiting on <0x89444e38> (a com.clustercontrol.agent.Agent) at java.lang.Object.wait(Unknown Source) at com.clustercontrol.agent.Agent.main(Agent.java:111) - locked <0x89444e38> (a com.clustercontrol.agent.Agent) "VM Thread" prio=1 tid=0x083082f8 nid=0x1bc1 runnable "VM Periodic Task Thread" prio=1 tid=0x08314630 nid=0x1bc7 waiting on condition num #instances #bytes class name -------------------------------------- 1: 1433 183216 <no name> 2: 3165 169256 <symbolKlass> 3: 1294 155992 [C 4: 184 92064 <constantPoolKlass> 5: 293 88072 [I 6: 218 82776 [B 7: 1433 80280 <methodKlass> 8: 184 68560 <instanceKlassKlass> 9: 155 49168 <constantPoolCacheKlass> 10: 1320 31680 java.lang.String 11: 255 24480 java.lang.Class 12: 62 18848 <objArrayKlassKlass> 13: 259 14760 [S 14: 326 12896 [Ljava.lang.Object; 15: 288 10656 [[I 16: 296 7104 java.util.HashMap$Entry 17: 84 6568 [Ljava.util.HashMap$Entry; 18: 162 5184 java.lang.ref.SoftReference 19: 207 4968 java.util.Hashtable$Entry ・・・途中省略・・・ 308: 1 8 java.util.jar.JavaUtilJarAccessImpl Total 13634 1174392