トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS

Java:スレッドダンプをとる

Last-modified: 2013-08-24 (土) 02:14:21 (3891d)
Top / Java:スレッドダンプをとる

Java:スレッドダンプをとる

こんな状況ありませんか?

JAVAのプログラムがOutOfMemoryError?を出力していて、もしかしたらメモリリークのおそれがある、けど、どうやって特定したらよいか、方法がわからない。

そんなとき、

  • 実行中のプログラムを一時停止することが可能(運用的に)
  • 実行中のVMのFULLGCを実行することが可能(運用的に)

であれば、一手間かけることでJAVAVM中のスレッドダンプを出力することが出来ます。

手順

至って簡単です。

  1. javaの起動オプションに
    -XX:+PrintClassHistogram

    を追加する

  2. VMを再起動する
  3. 再起動した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

参考サイト