備註:此文章參考《Java併發編程的藝術》
有很多問題在開發環境下並不會出現,在生產環境下才會出現,而在生產環境下又不能調試代碼,只能根據線上日誌,系統狀態,dump線程來定位問題
一.查看每一個進程的狀態
使用命令:top
user:表示當前登錄該機器的用戶數
load average:一分鐘負載,五分鐘負載,十分鐘負載(每隔5秒鐘檢查一次活躍的進程數,然後按特定算法計算出的數值,這個數除以邏輯CPU的數量,結果高於5的時候就表明系統在超負荷運轉)
第二行表示:系統一共有255個進程,3個處於運行狀態,252個處於休眠狀態,0個處於停止狀態,0個殭屍進程
第三行表示:
1.8%us(user):用戶空間佔用CPU的百分比
3.0%sy(system):內核空間佔用CPU的百分比
0.0%ni(nice):改變過優先級的進程佔用CPU的百分比
95.2%id(idle):空閒CPU百分比
0.0%wa(wait):IO等待佔用CPU的百分比
0.0%hi(hardware interrupts):硬中斷佔用CPU的百分比
0.0%si(software interrupts):軟中斷佔用CPU的百分比
第四行表示:物理內存總量,使用中的內存總量,空閒內存總量,緩存的內存量
第五行表示:交換區內存總量,交換區使用中的內存總量,交換區空閒內存總量,交換區緩存的內存總量
二.再使用top的交互命令數字1查看每個CPU的性能數據
由於顯示到CPU7,所以可以知道該服務器是一臺8核的虛擬機,如果這裏CPU的使用率達到了100%,則有可能出現死循環
三.使用top的交互命令H查看每個線程的性能信息
線程信息分三種情況:
1.某個線程CPU一直100%,說明該線程有可能出現死循環
2.某個線程一直再top10的位置,說明這個線程有可能有性能問題
3.CPU利用率高的幾個線程在不停變化,說明不是由某一個線程導致CPU偏高
第一種情況,有可能是垃圾回收導致的,使用jstat命令查看GC情況,看看是不是持久代或年老代滿了,產生FullGC,導致CPU利用率繼續飆高。
方法一:jstat -gcutil pid 1000 5
方法二:把線程dump下來,查看是哪個線程、執行什麼代碼導致CPU利用率高
jstatck pid > ./dump
dump出來的線程ID是十六進制的,而使用top命令看到的線程ID是十進制的,需要用printf命令轉換一下
printf "%x\n" pid