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