@
本文將通過一個簡單的案例,展示幾下幾點:
如何定位是哪個服務進程導致CPU過載
哪個線程導致CPU過載
哪段代碼導致CPU過載
首先是寫一個死循環的代碼demo,用於模擬cpu100%的場景(此處不一定達到100%,只是為了演示排查過程盡量模擬)
public class BusyCpu {
public static void main(String[] args) {
new Thread() {
@Override
public void run() {
int result = 0;
while (true) {
result++;
if (result > Integer.MAX_VALUE / 2) {
result = 0;
}
System.out.println(result);
}
}
}.start();
}
}
詳細步驟
1. 定位哪個服務導致的cpu滿載
方法:
- 執行
top -c
,顯示進程運行信息列表 - 鍵入
P (大寫p)
,進程按照CPU使用率排序

2. 定位哪個線程導致的cpu滿載
上面已經找到最耗cpu的進程,在此基礎上,可以尋找耗cpu的線程
方法:
top -Hp 187968
,顯示指定進程的線程運行信息列表- 鍵入
P (大寫p)
,線程按照CPU使用率排序

從上圖看出,進程187968中最耗cpu的線程是187990
3. 查看堆棧,定位到具體代碼段
上面已經找到具體的線程,接下來可以通過在堆棧信息中,查看具體的代碼段和相關信息。
首先:
上面線程號是10進制,在堆棧信息中,線程號是16進制,因此可以先通過命令轉換為16進制
> printf "%x\n" 187990
2de56
其次方法:
找到進程中的堆棧信息,然后按照線程號查找相關信息
- 打印進程堆棧
- 通過線程id(16進制),過濾得到線程堆棧
> jstack 187968 > temp.stack
