Linux平臺上的Java應用CPU問題定位——以WebSphere爲例

Linux上使用命令top -H,即可看到使用CPU高的線程號,轉換成16進制即可
1. 獲得最頂端輸出並查找與之前啓動了現佔用 CPU 的 WAS 的那個用戶 ID 相關聯的 PID。
2. 通過 kill -3 <PID> 對 WebSphere Application Server 進行若干 Thread Dump

(如果是Oracle JDK,可使用jstack <pid>來收集javacore)

3. 將步驟 1 中的 PID 號轉換爲一個十六進制值。
4. (用於 Linux 的 JVM 將 Java 線程作爲本地線程實現,這使每個線程成爲一個獨立的 Linux 進程。)
5. 在 Thread Dump 中搜索native ID 的值等於上一步驟中所得到的十六進制值的線程。 這將爲你揭示造成高 CPU 佔用率問題的線程。
下面是 Linux 系統中上述進程的一個示例:
在 Linux 中,每個線程映射到一個進程中,所以可以找到PID。
PID    USER    PRI    NI    SIZE    RSS    SHARE    STAT     %CPU    %MEM    TIME    COMMAND
...........
22962    usera    9        0    86616    84M    26780        S            0.0            4.2        0:00        java
...........

如果 PID 爲 22962,則十六進制值將是:0x59B2
使用此十六進制值並在 Thread Dump 中查找哪個 native ID 等於該值,以便從 Thread Dump 中獲取正確的線程。
例如,如果某個線程出現問題,則 0x59B2 將對應於該線程:
3XMTHREADINFO      "Servlet.Engine.Transports:915" (TID:0x34B82C78, sys_thread_t:0x778F7670, state:MW, native ID: 0x59B2) prio=5
       at java.lang.Object.wait(Native Method)
        at java.lang.Object.wait(Object.java:415)
        ……
然後,您可以檢查該線程以確定它正在執行的任務以及是否出現問題。
在上述示例中,由於該線程此時佔用 0% 的 CPU,所以只顯示執行此操作的進程。理想狀態下,應當迅速並且連續完成全部三個步驟,以便儘可能及時地捕捉數據。這可以通過類似下面的一個簡單的 shell 腳本來完成。

# Takes an argument (PID of the WAS process) and loops three times.  This will append the prstat information to a file called dump_high_cpu.txt.  The thread dump information will either be in file where stdout was redirected or printed on the screen.

for loopnum in 1 2 3
do
   top -b -n1>> dump_high_cpu.txt
   kill -3  $1
   echo "cpu snapshot and thread dump done. #" $loopnum
   sleep 1
   echo "Done sleeping."
done

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章