http://blog.leanote.com/post/github-yihengliucc/linux-cpu%E5%8D%A0%E7%94%A8%E7%8E%87%E5%88%86%E6%9E%90
使用top命令查看可能會有進程佔用率非常高,這個數值是進程內各個線程佔用cpu的累加值。
關於第三行CPU(s)的理解為:
%us 使用者空間佔用CPU百分比,當有多個CPU時,則分母為全部CPU計算能力之和。
%sy 核心空間佔用CPU百分比,當有多個CPU時,則分母為全部CPU計算能力之和。
單個進程的CPU的利用率理解為:
當前任務共用從上次螢幕重新整理時的CPU時間,以CPU總時間的百分比表示。在一個真實的SMP環境中,如果Irix Mode被設定成off,top將工作在Solaris Mode下,即一個任務的CPU利用率將以CPU的總數分開顯示,要切換Irix/Solaris Mode,按I就行。
比如進程佔用各CPU使用率總和為10%,則TOP命令顯示結果為160%(10%*16核),所以當前圖片中Tomcat實際佔用各CPU總和使用率為106%/16=6.625%與主機總體負載基本一致。
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 14094 root 15 0 315m 10m 7308 S 891% 2.2 1:49.01 gateway 使用top -H p pid 命令可以查看進程內各個線程佔用CPU百分比
top中可以看到有107個線程,但是下面9個線程佔用CPU很高,下面以線程14086為主,分析其為何high CPU PID USER PR NI VIRT RES SHR S %CPU MEM TIME+ COMMAND 14086 root 25 0 922m 914m 538m R 101 10.0 21:35.46 gateway 14087 root 25 0 922m 914m 538m R 101 10.0 10:50.22 gateway 14081 root 25 0 922m 914m 538m S 99 10.0 8:57.36 gateway 使用命令gstack查看進程中各個線程的函數調用棧
gstack pid > gstack.log,這裡的pid是上面查出的
#gstack 14094 > gstack.log 在gstack.log中尋找線程ID14086,由於函數棧會暴露函數細節,因此只顯示了兩個函數楨,線程ID14086對應線程號是37 Thread 37 (Thread 0x4696ab90 (LWP 14086)): #0 0x40000410 in __kernel_vsyscall () #1 0x40241f33 in poll () from /lib/i686/nosegneg/libc.so.6 使用命令gcore可以中繼程序映像及記憶體上下文
gcore pid 改命令產生core.pid檔案
#gcore 14094 該命令產生core檔案core.14094 使用strace命令查看系統調用和花費的時間
strace -T -r -c -p pid,-c參數顯示統計資訊,去掉此參數可以查看每個系統調用話費的時間及傳回值。
% time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------------------- 99.99 22.683879 3385 6702 poll 用gdb調試core檔案,併線程切換到37號(進程號在gstack命令中可以看到)線程
gcore和實際的core dump時產生的core檔案幾乎一樣,只是不能用gdb進行某些動態調試 (gdb) gdb gateway core.14094 (gdb) thread 37 [Switching to thread 37 (Thread 0x4696ab90 (LWP 14086))]#0 0x40000410 in __kernel_vsyscall () (gdb) where #0 0x40000410 in __kernel_vsyscall () #1 0x40241f33 in poll () from /lib/i686/nosegneg/libc.so.6 可以根據詳細的函數棧進行gdb調試,列印一些變數值,並結合原始碼分析為何會poll調用佔用很高的CPU。 因為代碼涉及到公司產權,顧不在此做詳細分析,需要明白的是分析的流程和使用的命令。