スレッド ダンプの生成
操作の実行中に、Jira がフリーズしたように見える場合があります。そのような場合、スレッド ダンプ — Java 仮想マシン内で実行中のスレッドおよびプロセスに関する情報を含むログ — の取得が役立つ可能性があります。スレッド ダンプの取得は非破壊プロセスであるため、稼動中のシステム上で実施することができます。このドキュメントでは、スレッド ダンプの取得に必要な手順を説明します。
Jira を実行している OS によって、スレッド ダンプの取得手順が異なります。以降の適切な手順をご利用ください。
Windows 環境
startup.bat で実行している Jira の場合
- Jira を実行しているディレクトリのコマンド コンソール ウィンドウで、タイトル バーを右クリックしてプロパティ ダイアログ ボックスを開き、[プロパティ] を選択します。
- [Layout] タブを選択します。
- [Screen Buffer Size] で、[Height] を 3000 に設定します。
- [OK] をクリックします。
- 同じコマンド コンソールで CTRL-BREAK を押すと、コマンド コンソールにスレッド ダンプが出力されます。
- "Full thread dump" と書かれた行まで、コマンド コンソールをスクロールします。
- タイトル バーを右クリックし、[Edit] > [Mark] を選択します。スレッド ダンプのテキスト全体をハイライト表示します。
- タイトル バーを右クリックして、[編集] > [コピー] を選択します。スレッド ダンプがテキスト ファイルに貼り付けられるようになりました。
Windows サービスとして実行している Jira の場合
jstack を使用する場合
JDK には jstack という名前の、スレッド ダンプ生成用のツールが付属します。
- プロセスを特定します。
Ctrl + Shift + Esc
キーを押してタスク マネージャーを立ち上げ、 Java (Jira) プロセスのプロセス ID を検索します。[View
] > [Select Columns ...
] を使用して PID 列を追加する必要がある場合があります。 - 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 環境
Linux/Unix コマンドライン
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 :
スレッド ダンプを取得するには、次のコマンドを実行します。
kill -3 <pid>
ここで、pid がプロセス ID (この場合は 910) です。
- スレッド ダンプは、Tomcat のコンソール出力に記載されます。コンソール出力は
logs/catalina.out
ファイル (Jira スタンドアロン / インストーラーの場合は Jira アプリケーション インストール ディレクトリにあります) にリダイレクトされます。
Linux/Unix での代替手段: jstack を使用してスレッドダンプを生成する
スレッド ダンプを取得する際 kill -3 <pid> で問題が発生した場合、java ユーティリティ である jstack を使用し、指定したプロセスの Java スレッドのスタックトレースを出力します。
Jira を実行している java プロセスを特定します。これは次のようなコマンドで実現できます。
ps -ef | grep java
次のようなプロセスが見つかります。
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
jstack <pid> を実行して、単一のスレッドダンプ を取得します。このコマンドにより、プロセス ID <pid> のスレッドダンプ1個が取得出来ます。この場合のプロセス ID は22668です。出力は JIRAthreaddump.txt ファイルにロギングします。
adam@jiratrack:~$ jstack 22668 > JIRAthreaddump.txt
スレッドダンプを複数取得します。
通常、約 10 秒間隔でダンプを取得します。その場合、複数のダンプや出力されたスタックトレースを以下のように1つのファイルに生成することができます。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
Linux/Unix での代替手段: スクリプトを使用してスレッドダンプを生成する
また、サポート チームが作成したスクリプトを使用してスレッド ダンプを生成することもできます。これは簡単なプロセスで、スクリプトがすべての操作を実行します。スクリプトはスレッド ダンプを生成するだけでなく、ヒープ ダンプを生成、ディスクのアクセス速度や Java SSL 接続をチェックすることもできます。
- (オプション) お使いの Jira バージョンで Thready プラグインがサポートされている場合、それをインストールします。Thready は Tomcat スレッドの名前を変更し、スレッドを分析しやすくするよう、名前に URL を含めます。
- https://bitbucket.org/atlassianlabs/atlassian-support/ からスクリプトをダウンロードしてインストールします。
- Jira インスタンスの動作が遅い、または反応がない場合はスクリプトを実行します。
- (オプション) また、スクリプトにより、ディスクのアクセス速度をテストすることもできます。詳細は、「ディスクのアクセス速度のテスト」に記載されています。
- スレッド ダンプを取得するかどうかを尋ねられたら、「Y」を入力します。
- ヘッド ダンプを取得するかどうかを尋ねられたら、「Y」を入力します。
- (オプション) また、スクリプトで Java SSL 接続をチェックすることもできます。
- スクリプトを実行した後、スレッド ダンプが取得され、圧縮されます。これで、サポート チケットを開き、生成されたパッケージを添付できます。
分析ツール
スレッド ダンプを調査するには TDA や Samurai を使用します。
TDA
- TDA をダウンロードします。
- CD コマンドを JAR が存在するディレクトリに格納します。
次のコマンドを実行します。
java -jar -Xmx512M ~/tda-bin-1.6/tda.jar
- スレッドダンプが含まれている catalina.out ファイルを開きます。
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>