[TOC]
使用 JVM Jsatck 命令定位使服務(wù)器 CPU 爆炸的類(lèi) & 方法痕惋。
CentOS 7 服務(wù)下
首先給出一段示例代碼:
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Hello world!
*/
public class App {
private static final AtomicInteger atomic = new AtomicInteger(0);
private static final Integer randomInteger = new Random().nextInt(100);
private static final Object LOCK = new Object();
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
synchronized (LOCK) {
threadFunc();
atomic.addAndGet(1);
}
}
}
public static void threadFunc() {
new Thread(() -> {
if (randomInteger.equals(atomic.get())) {
// 這里會(huì)讓服務(wù)器出現(xiàn) CPU 100% 占用
while (!UUID.randomUUID().toString().equals("HELLO,WORLD!")) {
}
}
}).start();
}
}
使用 top 命令查看服務(wù)器資源占用情況
截屏2021-01-17 下午7.04.36.png
可以很明顯的看到 PID 為 14168 的 java 程序出現(xiàn)了 CPU 99.9 % 的占用
使用 Jvm jps 命令確認(rèn)占用CPU過(guò)高的程序
image.png
可以看到 14168 是名稱(chēng)為 APP 的程序谐鼎。
使用 Jvm jstack 命令打印出 dump 堆棧信息
jstack [pid] > ps.log
image.png
進(jìn)入 top 使用 shift + h 查看占用 CPU 較高的線(xiàn)程號(hào)
image.png
可以看到占用 CPU 較高的線(xiàn)程號(hào)是 14226
使用打印出的 dump 信息查看線(xiàn)程信息。
首先將 14226 轉(zhuǎn)換為 16 進(jìn)制楣富。
printf '%x\n' 14226
輸出3792
使用 grep -A 20 3792 ps.log
查看線(xiàn)程信息
image.png
可以看到是 App.java 文件 中的 threadFunc 方法。
總結(jié)
- Top 命令查看CPU過(guò)高的應(yīng)用
- 使用 Jps 命令定位程序
- 使用 jstack [pid] > [文件] 打印出 dump 文件
- 進(jìn)入 top 使用 shift + h 切換查看線(xiàn)程信息
- 使用 printf '%x\n' [tid] 將線(xiàn)程ID轉(zhuǎn)換為 16 進(jìn)制
- 進(jìn)入 dump 文件通過(guò)轉(zhuǎn)換過(guò)后的 16 進(jìn)制線(xiàn)程號(hào)愉老。搜索線(xiàn)程信息嚷节。定位類(lèi)和方法。
- 人工分析代碼BUG