天天看點

java優化之查找CPU瓶頸

分析cpu使用率

使用top、或pidstat指令檢視程序的cpu使用情況。

java優化之查找CPU瓶頸

1)top的詳細使用請參閱: http://my.oschina.net/xiaoqqq/blog/384482

PID為程序id, %CPU為程序消耗的cpu百分比, 預設是按照百分比降序排列的。

2)pidstat是sysstat中的指令,(官網:www.fhadmin.org)  使用之前需要先安裝sysstat, yum install sysstat安裝即可。

安裝完成後輸入pidstat 2 2, 表示每個2秒輸出一次程序資訊, 一共輸出2次, 顯示如下:

java優化之查找CPU瓶頸

其中cpu清單示該程序占用的cpu數量(官網:www.fhadmin.org) 。

如果要檢視某一程序的cpu使用資訊, 則使用pidstat -p pid -t period count 指令檢視。

如pidstat -p 1642 -t 2 2顯示如下資訊:

java優化之查找CPU瓶頸

其中TGID表示程序id, tid表示線程id, %system表示cpu使用率, %CPU表示該程序的cpu使用百分比。 %system這個在top指令中是檢視不到的。

3) vmstat檢視cpu、記憶體、io采樣資料。

輸入 vmstat 1 2 可獲得如下顯示資訊:

java優化之查找CPU瓶頸

一般指令格式為(官網:www.fhadmin.org) vmstat 采樣時間間隔  [采樣次數]

輸出内容含義如下:

r 表示運作隊列(就是說多少個程序真的配置設定到CPU),我測試的伺服器目前CPU比較空閑,沒什麼程式在跑,當這個值超過了CPU數目,就會出現CPU瓶頸 了。這個也和top的負載有關系,一般負載超過了3就比較高,超過了5就高,超過了10就不正常了,伺服器的狀态很危險。top的負載類似每秒的運作隊 列。如果運作隊列過大,表示你的CPU很繁忙,一般會造成CPU使用率很高。

b 表示阻塞的程序,這個不多說,程序阻塞,大家懂的。

swpd 虛拟記憶體已使用的大小,如果大于0,表示你的機器實體記憶體不足了,如果不是程式記憶體洩露的原因,那麼你該更新記憶體了或者把耗記憶體的任務遷移到其他機器。

free   空閑的實體記憶體的大小,我的機器記憶體總共8G,剩餘3415M。

buff   Linux/Unix系統是用來存儲,目錄裡面有什麼内容,權限等的緩存,我本機大概占用300多M

cache cache直接用來記憶我們打開的檔案,給檔案做緩沖,我本機大概占用多M(這裡是Linux/Unix的聰明之處,把空閑的實體記憶體的一部分拿來做檔案和目錄的緩存,是為了提高 程式執行的性能,當程式使用記憶體時,buffer/cached會很快地被使用。)

si  每秒從磁盤讀入虛拟記憶體的大小,如果這個值大于,表示實體記憶體不夠用或者記憶體洩露了,要查找耗記憶體程序解決掉。我的機器記憶體充裕,一切正常。

so  每秒虛拟記憶體寫入磁盤的大小,如果這個值大于,同上。

bi  塊裝置每秒接收的塊數量,這裡的塊裝置是指系統上所有的磁盤和其他塊裝置,預設塊大小是byte,我本機上沒什麼IO操作,是以一直是,但是我曾在處理拷貝大量資料(T)的機器上看過可以達到/s,磁盤寫入速度差不多M每秒

bo 塊裝置每秒發送的塊數量,例如我們讀取檔案,bo就要大于。bi和bo一般都要接近,不然就是IO過于頻繁,需要調整。

in 每秒CPU的中斷次數,包括時間中斷

cs 每秒上下文切換次數,例如我們調用系統函數,就要進行上下文切換,線程的切換,也要程序上下文切換,這個值要越小越好,太大了,要考慮調低線程或者程序的 數目,例如在apache和nginx這種web伺服器中,我們一般做性能測試時會進行幾千并發甚至幾萬并發的測試,選擇web伺服器的程序可以由程序或 者線程的峰值一直下調,壓測,直到cs到一個比較小的值,這個程序和線程數就是比較合适的值了。系統調用也是,每次調用系統函數,我們的代碼就會進入核心 空間,導緻上下文切換,這個是很耗資源,也要盡量避免頻繁調用系統函數。上下文切換次數過多表示你的CPU大部分浪費在上下文切換,導緻CPU幹正經事的 時間少了,CPU沒有充分利用,是不可取的。

us 使用者CPU時間,我曾經在一個做加密解密很頻繁的伺服器上,可以看到us接近,r運作隊列達到(機器在做壓力測試,性能表現不佳)。

sy 系統CPU時間,如果太高,表示系統調用時間長,例如是IO操作頻繁。

id  空閑 CPU時間,一般來說,id + us + sy = ,一般我認為id是空閑CPU使用率,us是使用者CPU使用率,sy是系統CPU使用率。

wt 等待IO CPU時間。                

4) ps檢視程序、線程資訊, 具體不再描述。

5)sar檢視曆史程序資訊。

我們使用top指令分析,(官網:www.fhadmin.org)  可以發現CPU使用率過高主要展現在us、sy、wa、hi。其中wa的值是受IO等待影響的, IO等待時間越長,wa的值越高, hi的值受硬體中斷影響, 主要包括磁盤讀寫、網卡收發資料等, 對于java程式來說, 分析uy、sy就夠了。

1) us表示的意思是使用者空間占用cpu百分比, 他的值過高, 就說明是應用程式消耗了過多的cpu資源, 對于java應用來說主要是因為線程一直在循環操作、正則比對、者大量的計算,或者頻繁的GC。加入用戶端的每次請求, 服務端都要配置設定較多的記憶體, 那麼請求量大的時候就會導緻不斷的GC, 影響系統性能, 進而造成請求堆積,消耗更多記憶體, 反複如此, 進入惡性循環中。 對于前幾種情況, 就要我們找到消耗cpu的線程, 分析對應的代碼, 找到影響性能的部分, 來解決問題, 對于頻繁GC的問題, 就要通過分析jvm來查找原因, 随後我會寫一篇針對jvm記憶體分析的文章來進行詳解。

查找消耗CPU線程的方法kill -3 pid或者jstack pid導出線程資訊, 然後将pid轉化為16進制, 在導出的線程資訊中找到即可。(當jvm執行個體挂起後, kill -3是無法導出線程資訊的)

2)sy值過高說明linux系統cpu耗費很多資源來進行線程切換, 對于java程序來說就是啟動了過多的線程,且線程不斷的阻塞或者狀态不斷變化, 這就導緻作業系統要不斷的切換線程。分析的時候通過kill -3或者jstack導出線程資訊, 檢視線程資訊、鎖資訊, 分析解決問題。

繼續閱讀