cpu性能消耗分析


在Linux中,CPU主要用於中斷、內核以及用戶進程的任務處理,優先級為中斷>內核>用戶進程,在學習如何分析CPU消耗狀況前。先要掌握三個重要的概念

1、上下文切換

每個CPU在同一時間只能執行一個線程,Linux采用的是搶占式調度,即為每個線程分配一定的執行時間,當到達執行時間、線程中有IO阻塞或高級優先線程要執行時,Linux將切換執行線程,在切換時要存儲目前線程的執行狀態,並要恢復要執行的線程狀態,這個過程稱為上下文切換。對於java應用,典型的是進行文件IO操作、網絡IO操作、鎖等待或線程sleep時,當前線程會進入阻塞或休眠狀態,從而促發上下文切換,上下文切換過多會造成內核占據較多的CPU使用,使得應用的相應速度下降。

2、運行隊列

每個CPU核都維護了一個可運行的線程隊列,例如一個4核的CPU,JAVA應用中啟動了8個線程。且這8個線程都初一可運行的狀態,那么在分配平均的情況下每個CPU中運行隊列里就會有兩個線程。通常而言,系統的load主要由cpu的運行隊列來決定,假定以上狀況運行維持了1分鍾,那么這1分鍾內系統load就會是2,但用於load是個復雜的值,因此也不是絕對的,運行隊列值越大,就意味着線程會要消耗長時間才能執行完。Linux System and NetWork Performance Monitoring中建議控制在每個cpu核上的運行隊列為1~3個。

3、利用率

CPU利用率為CPU在用戶進程、內核、中斷處理、IO等待以及空閑五個部分使用百分比,這5個值用來分析CPU消耗情況的關鍵指標。Linux System and NetWork Performance Monitoring中建議用戶的CPU消耗/內核的CPU消耗的比率在65%~70%/30%~35%左右。

使用top命令查看

top - 23:22:02 up  5:47,  1 user,  load average: 0.00, 0.00, 0.00
Tasks: 107 total,   1 running, 106 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.3%us,  0.3%sy,  0.0%ni, 99.3%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   1017464k total,   359292k used,   658172k free,    56748k buffers
Swap:  2064376k total,        0k used,  2064376k free,   106200k cached
此信息關注第三行信息

0.4%us表示用戶處理進程所占的百分比;0.3%sy表示內核線程處理所占的百分比;0.0%ni表示被nice命令改變優先級的任務所占的百分比;99.3%id表示CPU的空閑時間所占的百分比;0.0%wa表示為在執行過程中等待IO所占的百分比;0.0%hi表示硬件中斷所占的百分比,0.0%si表示為軟件中斷所占的百分比。

對於多核或者對歌CPU,上面的顯示或是多個cpu所占用的百分比的綜合,因此會出現160%us這樣的現象,如需要查看每個核的消耗情況,可在進入top視圖后按1,就會按核來顯示消耗情況

默認情況下top視圖中顯示的為進程的CPU消耗狀況,在top視圖中按shift+h后,可按線程查看CPU的消耗狀況,

                                                                                                                        
 1313 root      20   0  165m 3848 3024 S  0.0  0.4   0:05.06 vmtoolsd                                                                                                                          
 2767 xubo      20   0 14940 1176  904 R  0.3  0.1   0:02.93 top                                                                                                                               
    1 root      20   0 19228 1428 1148 S  0.0  0.1   0:01.86 init                                                                                                                              
 1949 root      20   0  150m  20m 4976 S  0.0  2.0   0:01.58 Xorg                                                                                                                              
 2076 gdm       20   0  363m  14m  10m S  0.0  1.5   0:01.01 gdm-simple-gree    

還可以使用pidstat  vmstat

pidstat是SYSSTAT中的工具,如須使用pidstat,請先安裝SYSSTAT


當CPU消耗嚴重時,主要體現在us、sy、wa或hi的值變高,wa的值是IO等待造成的,hi的值變高主要是硬件中斷造成的,例如網卡接收數據頻繁的狀況。

對於java應用而言,CPU消耗嚴重主要體現在us、sy兩個值上,分別看看java應用在兩個值高的情況下應如何尋找對應造成平靜的 代碼。

1 、us

當us值過高時,表示運行的應用消耗了大部分的CPU。在這宗情況下,對JAVA應用而言,最重要的為找到具體消耗CPU的線程所執行的線程執行代碼,可采用如下犯法做到。

首先通過linux提供的命令找到消耗CPU嚴重的線程及其ID,將線程ID轉化為十六進制的值。之后通過 kill -3 [javapid]或jstack的方式dump出應用的java線程信息,通過之前轉化出的十六進制的值找到對應的nid值的線程。該線程即為消耗CPU的線程,在采樣時候須執行幾次上述的過程,確保找到真實消耗CPU的線程

java應用造成us高的原因主要是線程一直處於可運行狀態,通常是這些線程在執行無阻塞、循環、正則或純粹的計算等動作造成;另外一個可能是頻繁GC。如每次請求都需要分配較多的內存,當訪問量搞的時候就將導致不斷地進行GC,系統響應速度下降,進而造成堆積的請求更多,消耗的內存更嚴重,最嚴重的時候有肯能會導致系統不斷的驚醒Full GC,對於頻繁GC的狀況要通過分析JVM內存消耗來查找原因

具體事例:請參考分布式java應用180頁

2、sy

當sy值高時,表示Linux花費了更多的時間在進行線程切換,Java應用造成這種現象的主要原因是啟動的線程比較多,且這些線程多數處理不斷的阻塞(如鎖等待、IO等待狀態)和執行狀態的編號過程中,這就導致了操作系統要不斷切換執行的線程,產生大量的上下文切換。在這種狀況下,對Java應用,最重要的是找出線程不斷切換狀態的原因。

查找過程工us一樣

原文鏈接:https://blog.csdn.net/xubo_zhang/article/details/8574040


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM