我該如何在 UNIX 或 Windows 上收集 JVM 的執行緒傾印?

執行緒傾印是目前在 Java 虛擬機器 (JVM) 中執行的所有 Java 執行緒清單。

下列為數種收集 JVM 執行緒傾印的方式。我們也強烈建議您收集多個執行緒傾印。每隔一段時間收集 10 個執行緒傾印是個好方法,例如每 10 秒收集一個執行緒傾印。

步驟 1:取得 Java 程序的 PID

如果要取得執行緒傾印,所需的第一筆資訊就是 Java 程序的 PID。

Java JDK 會附上列出所有 Java 程序識別碼的 jps 命令。您可以執行以下命令:

jps -l 70660 sun.tools.jps.Jps 70305

注意:在 Linux 和 UNIX 中,您可能必須以 sudo -u user jps -l 執行此命令,且 Java 程序需以使用者名稱為「user」的使用者身分執行。

若無效或您仍無法找到您的 Java 程序 (未設定路徑、未安裝 JDK 或為舊版 Java),請使用

  • UNIX、Linux 和 Mac OS X:ps -el | grep java
  • Windows:按 Ctrl+Shift+Esc 鍵以開啟工作管理員,然後找到 Java 程序的 PID

步驟 2:請求 JVM 的執行緒傾印

jstack

如果已安裝/可使用 jstack 工具,我們建議使用該工具。此工具會將執行緒傾印列印至命令列主控台。

若要透過 jstack 取得執行緒傾印,請執行以下命令:
jstack -l <pid>

您可以將連續執行緒傾印輸出至檔案,方法為使用主控台輸出重新導向/附加指示詞:
jstack -l <pid> >> threaddumps.log

注意:

  • JDK 1.5 後才可使用 jstack 工具 (若為 Windows 上的 JVM,則僅限部分版本的 JDK 1.5 和 JDK 1.6 可使用)。
  • 即使啟用 -Xrs jvm 參數,仍可使用 jstack
  • 無法使用 JDK 1.6 的 jstack 工具,收集在 JDK 1.5 上執行之程序的執行緒傾印。
  • 在 Linux 和 UNIX 中,您必須以擁有下列 Java 程序之使用者的身分執行命令:
    sudo -u <java-user> jstack -l <pid>  
    (應以執行 Java 程序的使用者 ID 取代 <java-user>)
  • 如果您在 Windows 中執行 jstack並收到「存放體空間不足,無法處理此命令」錯誤訊息,則必須以 Windows「系統」使用者或是擁有該 Java 程序之使用者的身分執行 jstack。  您可在此下載 psexec,以使用該軟體執行此步驟。若要以「系統」使用者的身分執行 jstack,請使用類似下列命令:
    psexec -s jstack <pid>  >> threaddumps.log
    若您無法於伺服器上安裝 psexec,您可以建立一個包含該命令的 .bat 檔案,並使用 Windows 工作排程器 (以不同使用者的身分) 加以執行
  •  有時候,必須在 64 位元的系統上加入 -J-d64 選項,例如:
    jstack -J-d64 -l <pid> >> threaddumps.log

jstack 指令碼

此為收集自 eclipse.org 的一段指令碼,可利用 jstack 收集一系列執行緒傾印。 它也會使用 top 命令來擷取執行緒層級 CPU 使用量。

#!/bin/bash
if [ $# -eq 0 ]; then
    echo >&2 "Usage: jstackSeries <pid> <run_user> [ <count> [ <delay> ] ]"
    echo >&2 "    Defaults: count = 10, delay = 0.5 (seconds)"
    exit 1
fi
pid=$1          # required
user=$2         # required
count=${3:-10}  # defaults to 10 times
delay=${4:-0.5} # defaults to 0.5 seconds
while [ $count -gt 0 ]
do
    sudo -u $user top -H -b -n1 -p $pid >top.$pid.$(date +%H%M%S.%N) &
    sudo -u $user jstack -l $pid >jstack.$pid.$(date +%H%M%S.%N)
    sleep $delay
    let count--
    echo -n "."
done

 

使用以下方式執行 jstack:
sh jstackSeries.sh [pid] [cq5serveruser] [count] [delay]

例如:
sh jstackSeries.sh 1234 cq5serveruser 10 3

  • 1234 為 Java 程序的 pid
  • cq5serveruser 是 Linux 或 UNIX 使用者,執行 Java 程序時所使用的身分
  • 10 為收集的執行緒傾印數量
  • 3 為每次傾印間的延遲時間

注意:top 輸出擁有十進位格式的原生執行緒 ID,jstack 輸出則擁有十六進位格式的 NID。 透過將執行緒 ID 轉換為十六進位格式,您可以將 top 輸出的高 CPU 執行緒配對至 jstack 輸出。

Adobe Experience Manager 的執行緒傾印工具

如果您使用的是 Adobe Experience Manager 產品,則您只要安裝此工具,便可擁有可產生執行緒傾印的簡易使用者介面。

其他取得執行緒傾印的方式

如果無法使用 jstack 工具,則您可以採取下列方式收集執行緒傾印:

注意:如果已啟用 -Xrs 命令列參數,部分工具就無法收集 JVM 的執行緒傾印。如果您遭遇收集執行緒傾印的問題,請檢視此選項是否已啟用。

UNIX、Mac OS X 和 Linux (JDK 1.4 或舊版)

在 UNIX、Mac OS X 和 Linux 系統上,您可以將 QUIT 訊號傳送至 Java 程序,告知 Java 程序將執行緒傾印輸出為標準輸出。

  1. 執行以下命令以進行此操作:
    kill -QUIT <pid>
    您可能必須以 sudo -u user kill -QUIT <pid> 執行此命令,且 Java 程序需以「user」使用者身分執行。
  2. 如果您使用 crx-quickstart/server/start 指令碼開始 CQSE,則會將您的執行緒傾印輸出為 crx-quickstart/server/logs/startup.log。如果您使用 JBoss、WebSphere、Tomcat 等第三方應用程式伺服器,請參閱該伺服器的文件,以找到標準輸出導向的檔案。
Windows:
JDK 1.X
  1. 下載 javadump.exe (附於下方)。
  2. 透過下列三個引數啟動 JVM (必須依照正確順序):
    -XX:+UnlockDiagnosticVMOptions -XX:+LogVMOutput -XX:LogFile=C: mpjvmoutput.log
  3. 按 Ctrl+Shift+Esc 鍵,開啟「工作管理員」。
  4. 找到 Java 程序的 PID。
  5. 在命令列中,執行
    javadump.exe [pid]
  6. 執行緒傾印隨即會顯示於步驟 2 中提及的 jvmoutput.log 檔案中。
JDK 1.6

使用增效模組 [0],從 jconsole 工具取得執行緒傾印

以下是可請求執行緒傾印的方式:

  1. 將以下參數新增至執行 Communique 的 jvm:-Dcom.sun.management.jmxremote
  2. 下載並安裝 JDK 1.6 (若未安裝)。
  3. 下載 Thread Dump Analyzer 公用程式並解壓縮。[1]
  4. 執行 JDK 1.6 的 jconsole.exe
                                jconsole.exe -pluginpath /path/to/file/tda.jar
  5. 按一下「Thread dumps」(執行緒傾印) 標籤。
  6. 按一下「Request Thread Dump」(要求執行緒傾印) 連結。

注意:如果您執行的是 CQ5 及/或 CRX (透過 Sling),而且想監督正在執行的執行緒,則您可以請求 http://<主機>:<連接埠>/system/console/threads 以取得執行緒清單。但請注意,這些執行緒傾印無法搭配 samurai 或 tda 等執行緒傾印分析工具使用。

套用對象

在 JVM 中執行的所有 Adobe 產品

[0] http://technet.microsoft.com/zh-tw/sysinternals/bb897553.aspx
[1] https://github.com/irockel/tda
[2] http://docs.day.com/tw/home/docutools/javadump_exe.html

下載

此産品由 Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License 授權  Creative Commons 條款未涵蓋 Twitter™ 與 Facebook 文章。

法律說明   |   線上隱私權政策