使用自動化shell指令碼尋找CPU使用的詳細線程資訊
項目加了些攔截器代碼後,CPU警示,顯示CPU使用率超過100%;
想要尋找到底是哪些代碼消耗的資源過多,從網上找到一篇博文,轉載如下:
http://blog.csdn.net/guixunlong/article/details/8450897
在知道哪個Java進程CPU佔用率過高以後: 1.使用命令 jstack PID 命令列印出CPU佔用過高進程的線程棧,例如jstack 12012 > 12012.txt 2.使用top -H -p PID 命令查看對應進程是哪個線程佔用CPU過高. 比如:
可以看到,線程號為12025的線程佔用cpu很高,接下來就可以在12012.txt中尋找該線程,看它為啥這麼忙了 或者也可以採用ps命令 ps -mp pid -o THREAD,tid,time 或者 ps -Lfp pid 來查看繁忙的線程資訊
這個命令的作用,主要是可以擷取到對應一個進程下的線程的一些資訊。 比如你想分析一下一個java進程的一些運行瓶頸點,可以通過該命令找到所有當前Thread的佔用CPU的時間,線程號為tid列。
3.在jstack dump出來的檔案中尋找目錄線程,需要注意的是用16進程數來表示線程號,所以我們可以找12025對應的16進程數2EF9
圖中黃色文字即為線程id值 nid : 對應的Linux作業系統下的tid線程號,也就是前面轉化的16進位數字 tid: 這個應該是jvm的jmm記憶體規範中的唯一地址定位 |
按照博主的步驟,的確找到的詳細的線程資訊(非常感謝博主!)。
只是步驟有些繁瑣,在緊急時刻,分秒必爭,該方法顯然會浪費不少時間。
於是想根據博主的步驟,寫個自動化的指令碼。
經過多次的執行和分析,功夫不負有心人,終於寫出了滿足條件的shell指令碼,
直接調用該指令碼,無需任何參數,即可執行;該指令碼能在筆者工作的各個生產環境中使用。
現將該指令碼內容貼出如下,並在代碼中添加了注釋,供各位參考;該指令碼不一定滿足各種環境,請自行修改。
筆者水平有限,錯誤在所難免。歡迎批評指正。
#!/bin/bash########################################################### 尋找佔用CPU資源過高的線程詳細資料### ### 2014-11-03 allen add###########################################################Step1 列印佔用CPU過高的進程IDtop -b -d3 -n1 -u hotel | awk '/PID/,0' > ./_pid_out.outv_pid=`awk 'NR==2 {print $1}' ./_pid_out.out`#Step2 列印進程中佔用CPU過高的線程IDtop -b -d3 -n1 -H -p $v_pid | awk '/PID/,0' > ./_tid_out.outv_tid=`awk 'NR==2 {print $1}' ./_tid_out.out`#Step3 將線程ID轉為16進位#echo 'ibase=10;obase=16;$v_tid' | bcv_tid16=`printf %x $v_tid`echo "thread id[hexadecimal] is : 0x${v_tid16}"echo ""#Step4 列印CPU佔用過高的進程的線程棧echo "wait 5 seconds, please..."jstack $v_pid > ./_thread_stack.outsleep 5s#Step5 在 _thread_stack.out 中尋找線程執行的具體代碼,列印改行及其之後30行,並高亮顯示匹配內容cat ./_thread_stack.out | grep -n --color=auto -A 30 -i 0x${v_tid16}#cleanrm -rf ./_pid_out.outrm -rf ./_tid_out.out