スレッド ダンプの生成

操作の実行中に時折 JIRA がフリーズしたように見える場合があります。そのような場合、スレッド ダンプ — Java 仮想マシン内で現在実行中のスレッドおよびプロセスに関する情報を含むログ — の取り込みを行います。スレッド ダンプの取得は非破壊プロセスであるため、稼働中のシステム上で実施することができます。本書では、スレッド ダンプの取り込みに必要な手順を説明します。

The steps necessary to retrieve the thread dump are dependant on the operating system JIRA is running in — please follow the appropriate steps below.

On this page:

Windows Environment

startup.bat から JIRA を起動する

  1. JIRA 実行のコマンドコンソールウィンドウでタイトルバーを右クリックして、プロパティダイアログボックスを開き、「プロパティ」を選択します。
  2. [Layout] タブを選択します。
  3. Under Screen Buffer Size, set the Height to 3000.
  4. [OK] をクリックします。
  5. 開いているコマンド コンソール上で、CTRL-BREAK を押すと、コマンド コンソールにスレッド ダンプが出力されます。
  6. "Full thread dump" と書かれた行まで、コマンド コンソールをスクロールします。
  7. タイトルバーを右クリックし、編集 ->マークを選択します。スレッドダンプのテキスト全体をハイライト表示します。
  8. Right click the title bar and select Edit -> Copy. The thread dump can then be pasted into a text file.

JIRA running as a Windows Service

jstack を使用する場合

JDK と‬ jstack ツールが合体して、スレッドダンプを発生します。

  1. Identify the process. Launch the task manager by, pressing Ctrl + Shift + Esc and find the Process ID of the Java (JIRA) process. You may need to add the PID column using View -> Select Columns ...
  2. ‪‪jstack <pid>‬ を実行して、 単一のスレッドダンプを取得します。このコマンドで、プロセス ID ‪ <pid>‬ の1個のスレッドダンプが取得出来ます。この場合のプロセス ID は22668です。
C:\Users\Administrator>jstack.exe -l 22668 > threaddump.txt

このコマンドにより、現在のディレクトリに threaddump.txt というファイルが出力されます。

‪ jstack‬ のよくある問題

  • jstack は Jira を実行しているユーザーと同じユーザーとして実行する必要があります。
  • エラー メッセージ "Not enough storage is available to process this command" が表示された場合、ここから‪ "psexec" ユーティリティをダウンロードして、以下のコマンドを実行します。
    psexec -s jstack <pid> >> threaddumps.txt
  • 実行が可能な jstack が $PATH にない場合、<JDK_HOME>/bin ディレクトリで探します。
  • java.lang.NoClassDefFoundError: sun/tools/jstack/JStack が発生したら、JDK の lib ディレクトリ tools.jar があるかどうかを確認します。tools.jar がない場合、JDK のフル バージョンをダウンロードします。

Linux / Unix / OS X 環境

Using jstack and top

Please see Troubleshooting Jira performance with Thread dumps for a way to combine both top and jstack to provide the CPU output of individual threads along with their stack trace.

Linux/Unix Alternative: Command Line

  1. JIRA を実行している java プロセスを識別します。これは以下の様なコマンドで実現できます。

    ps -ef | grep java

    次のようなプロセスが見つかります。

    keithb     910   873  1 17:01 pts/3    00:00:18 /usr/java/jdk/bin/java -Xms128m -Xmx256m
    -Xms128m -Xmx256m -Djava.awt.headless=true -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
    -Djava.awt.headless=true -Djava.endorsed.dirs=/tmp/atlassian-jira-enterprise-3.6-standalone/common/endorsed
    -classpath :
  2. スレッド ダンプを取得するには、次のコマンドを実行します。

    kill -3 <pid>

    ここで、pid がプロセス ID (この場合は 910) です。

  3. The thread dump will be written to the Tomcat console output. The console output is redirected to the logs/catalina.out file, which can be found in the JIRA Installation Directory for JIRA Standalone / Installer, or for JIRA WAR, under the Tomcat installation directory.

Linux/Unix Alternative: Generating Thread Dumps using jstack

スレッド ダンプを取得する際 kill -3 <pid> で問題が発生した場合、java ユーティリティ である jstack を使用し、指定したプロセスの Java スレッドのスタックトレースを出力します。

  1. JIRA を実行している java プロセスを識別します。これは以下の様なコマンドで実現できます。

    ps -ef | grep java
  2. 次のようなプロセスが見つかります。

    adam 22668 0.3 14.9 1691788 903928 ? Sl Jan27 9:36 /usr/lib/jvm/java-6-sun-1.6.0.14/bin/java -Djava.util.logging.config.file=/home/adam/Products/installs/atlassian-jira-enterprise-4.0.1-standalone/conf/logging.properties -XX:MaxPermSize=256m -Xms128m -Xmx1048m -Djava.awt.headless=true -Datlassian.standalone=JIRA -Dorg.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER=true -Dmail.mime.decodeparameters=true -Datlassian.mail.senddisabled=false -Datlassian.mail.fetchdisabled=false -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs=/home/adam/Products/installs/atlassian-jira-enterprise-4.0.1-standalone/common/endorsed -classpath /home/adam/Products/installs/atlassian-jira-enterprise-4.0.1-standalone/bin/bootstrap.jar -Dcatalina.base=/home/adam/Products/installs/atlassian-jira-enterprise-4.0.1-standalone -Dcatalina.home=/home/adam/Products/installs/atlassian-jira-enterprise-4.0.1-standalone -Djava.io.tmpdir=/home/adam/Products/installs/atlassian-jira-enterprise-4.0.1-standalone/temp org.apache.catalina.startup.Bootstrap start
    
  3. Run jstack <pid> to Capture a Single Thread Dump
    This command will take one thread dump of the process id <pid>, in this case the pid is 22668, and log output to the file JIRAthreaddump.txt

    adam@jiratrack:~$ jstack 22668 > JIRAthreaddump.txt
    
  4. Take Multiple Thread Dumps
    Typically you'll want to take several dumps about 10 seconds apart, in which case you can generate several dumps and output the stack traces to a single file as follows:

    adam@jiratrack:~$ jstack 22668 >> JIRAthreaddump.txt
    adam@jiratrack:~$ jstack 22668 >> JIRAthreaddump.txt
    adam@jiratrack:~$ jstack 22668 >> JIRAthreaddump.txt
    

    RDP 経由でサーバーに接続している場合、jstack は以下のようなエラーで失敗する可能性があります。

    Not enough storage is available to process this command 

    コンソールモードで RDP セッションを開く必要があります: mstsc /admin

Analysis Tools

スレッド ダンプを調査するには TDASamurai を使用します。

TDA

  1. Download TDA
  2. CD to the directory where the JAR exists
  3. 次のコマンドを実行します。

    java -jar -Xmx512M ~/tda-bin-1.6/tda.jar
    
  4. Open your catalina.out file, containing the thread dump
TDA でスレッド ダンプを処理する場合の問題 (NumberFormatException)

TDA コンソールに次のようなエラーが表示されます。

Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string: "5 os_prio=0"
        at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
        at java.lang.Long.parseLong(Long.java:441)
        at java.lang.Long.<init>(Long.java:702)
        at com.pironet.tda.utils.ThreadsTableModel.getValueAt(ThreadsTableModel.java:80)
        at com.pironet.tda.utils.TableSorter.getValueAt(TableSorter.java:285)
        at javax.swing.JTable.getValueAt(JTable.java:2717)
        at javax.swing.JTable.prepareRenderer(JTable.java:5719)
        at javax.swing.plaf.basic.BasicTableUI.paintCell(BasicTableUI.java:2114)
        at javax.swing.plaf.basic.BasicTableUI.paintCells(BasicTableUI.java:2016)
        at javax.swing.plaf.basic.BasicTableUI.paint(BasicTableUI.java:1812)
        at javax.swing.plaf.ComponentUI.update(ComponentUI.java:161)
        at javax.swing.JComponent.paintComponent(JComponent.java:778)
        at javax.swing.JComponent.paint(JComponent.java:1054)
        at javax.swing.JComponent.paintChildren(JComponent.java:887)
        at javax.swing.JComponent.paint(JComponent.java:1063)
        at javax.swing.JViewport.paint(JViewport.java:731)
        at javax.swing.JComponent.paintChildren(JComponent.java:887)
        at javax.swing.JComponent.paint(JComponent.java:1063)
        at javax.swing.JComponent.paintChildren(JComponent.java:887)
        at javax.swing.JSplitPane.paintChildren(JSplitPane.java:1047)
        at javax.swing.JComponent.paint(JComponent.java:1063)
        at javax.swing.JComponent.paintToOffscreen(JComponent.java:5230)
        at javax.swing.BufferStrategyPaintManager.paint(BufferStrategyPaintManager.java:295)
        at javax.swing.RepaintManager.paint(RepaintManager.java:1249)
        at javax.swing.JComponent._paintImmediately(JComponent.java:5178)
        at javax.swing.JComponent.paintImmediately(JComponent.java:4989)
        at javax.swing.RepaintManager$3.run(RepaintManager.java:808)
        at javax.swing.RepaintManager$3.run(RepaintManager.java:796)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
        at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:796)
        at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:769)
        at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:718)
        at javax.swing.RepaintManager.access$1100(RepaintManager.java:62)
        at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1677)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:312)
        at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733)
        at java.awt.EventQueue.access$200(EventQueue.java:103)
        at java.awt.EventQueue$3.run(EventQueue.java:694)
        at java.awt.EventQueue$3.run(EventQueue.java:692)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:703)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

スレッド ダンプで次のコマンドを適用し、スレッド ヘッダー形式を修正して処理できるようにします:
sed -i 's/prio=[0-9]\{1,2\} os_prio=[0-9]\{1,2\}/prio=5/g' <filename>

Mac の場合:

sed -i '' 's/prio=[0-9]\{1,2\} os_prio=[0-9]\{1,2\}/prio=5/g' <filename>

スレッドダンプについて知りたい場合は、ナレッジベース記事をご参照ください:

最終更新日: 2016 年 10 月 12 日

この内容はお役に立ちましたか?

はい
いいえ
この記事についてのフィードバックを送信する
Powered by Confluence and Scroll Viewport.