一般而言cpu異常往往還是比較好定位的。原因包括業務邏輯問題(死迴圈)、頻繁gc以及上下文切換過多。而最常見的往往是業務邏輯(或者框架邏輯)導致的,可以使用jstack來分析對應的堆疊情況。
當使用jstack排查佔用率問題時,可以按照以下步驟進行:
top -H -p <pid>
該命令將顯示程序中各個執行緒的CPU使用率,以及執行緒的ID(TID)。
3. 根據執行緒ID(TID)獲取nid,可以使用以下命令:
printf '%x\n' <tid>
這將把TID轉換為16進位制格式的nid。
4. 然後,通過以下命令來檢視該執行緒的堆疊資訊:
jstack <pid> | grep 'nid' -C5 --color
該命令將顯示包含nid的堆疊資訊。注意,這裡使用了grep
命令來過濾輸出結果,只顯示包含nid的部分。-C5
表示在匹配項前後各顯示5行上下文資訊,--color
則用於在輸出中新增顏色標記。
5. 除了逐個檢視執行緒的堆疊資訊外,還可以對整個jstack檔案進行分析。可以使用以下命令來統計各個狀態的執行緒數量:
cat jstack.log | grep "java.lang.Thread.State" | sort -nr | uniq -c
該命令將輸出各個執行緒狀態的數量,例如RUNNABLE、BLOCKED、WAITING、TIMED_WAITING等。如果WAITING或TIMED_WAITING的數量較多,那麼可能存在一些問題。
通過以上步驟,我們可以使用jstack來定位佔用率較高的問題,並進一步分析問題原因。
通過使用jstat工具的-gc選項,我們可以觀察GC的分代變化情況,以便確定GC是否過於頻繁。具體來說,我們可以使用以下命令來觀察程序的GC情況:
jstat -gc <pid> 1000
在上述命令中,<pid>
是目標Java程序的PID,而1000
表示取樣間隔(以毫秒為單位)。通過這個命令,我們可以獲取關於Survivor區、Eden區、老年代(Old Generation)、後設資料區(Metaspace)的容量和使用量資訊,以及關於Young GC和Full GC的耗時和次數以及總耗時資訊。
具體來說,以下是一些關鍵指標的含義:
通過觀察這些指標,我們可以更好地瞭解Java程序的記憶體使用情況和垃圾回收情況。如果發現GC過於頻繁或存在其他問題,我們可以進一步分析並採取相應的優化措施。
上下文切換會消耗CPU的時間,並導致程序真正執行的時間縮短,從而成為系統效能下降的一個因素。過多的上下文切換可能會使得CPU花費過多的時間用於儲存和恢復暫存器、核心棧以及虛擬記憶體等資料,從而影響系統的響應速度和吞吐量。
vmstat是一個非常有用的系統效能分析工具,它可以提供關於系統記憶體、CPU活動、分頁和上下文切換等資訊。
在使用vmstat檢視上下文切換情況時,可以顯示以下統計資訊:
需要注意的是,vmstat命令的具體選項和輸出可能會因作業系統和版本而有所不同。在使用vmstat時,建議查閱相關檔案或使用"man vmstat"命令來獲取特定系統上vmstat的詳細使用說明和輸出解釋。
vmstat是給出整個系統總體的上下文切換情況,要想檢視每個程序的詳細情況就需要使用pidstat,加上-w選項就可以檢視程序上下文切換的情況 pidstat -w pid
命令,cswch和nvcswch表示自願及非自願切換。
cswch(voluntary context switches):表示每秒自願上下文切換的次數
nvcswch(non voluntary context switches):表示每秒非自願上下文切換的次數
系統上下文切換的次數為多少時是不正常的呢?
系統上下文切換的次數是否正常,取決於系統本身的CPU效能。一般來說,如果系統的上下文切換次數比較穩定,在數百到一萬以內,都應該算是正常的。然而,當上下文切換次數超過一萬次,或者切換次數出現數量級的增長時,就可能已經出現了效能問題。
具體遇到問題的時候,需要根據變化的上下文切換型別,再做具體分析。例如:自願上下文切換變多了,說明程序都在等待資源,有可能發生了I/O等其他問題;非自願上下文切換變多了,說明程序都在被強制排程,也就是都在爭搶CPU,說明CPU的確成了瓶頸;中斷次數變多了,說明CPU被中斷處理程式佔用,還需要通過檢視/proc/interrupts檔案來分析具體的中斷型別。