Java CPU 100% 场景复现与分析

列举 4 种 cpu 100% 的场景,之后会进行复现,以及对应的解决方案。

死循环

Java 代码

public class HelloWorld {
public static void main(String[] args) {
// 直接死循环
new Thread(() -> { while (true){ } }).start();
}
}

分析

  • top 分析进程使用资源情况

  • 执行 top -Hp 2581 可查看进程 2581 中的占用 CPU 的线程 ID 是 2592 。

  • 执行 16 进制的转换 printf "%x \n" 2592 得到 a20 的,再通过 jstack 命令定位出现问题的地方

大量 Full GC

Java 代码

public static void main(String[] args) {
//-XX:+UseSerialGC -Xms200M -Xmx200M -Xmn32m -XX:SurvivorRatio=8 -XX:+PrintGCDetails
byte[] newErdo = new byte[1024 * 1024 * 30];

while (true) {
// 触发 full gc
System.gc();
byte[] bytes = new byte[1024 * 1024 * 120];
}

}

分析

  • top 分析资源使用情况

  • 查看 gc 状态

线程计算耗时长

Java 代码

public static void main(String[] args) {
// 有复杂,耗时长的计算,导致 CPU 100%
work();
}

private static void work() {
// 利用 CPU 计算 π 的近似值
int i = Integer.MAX_VALUE;
double pi, temp = 0;
for (int j = 1; j <= i; j++) {
temp += Math.pow(-1, j + 1) / (2 * j - 1);
}
pi = 4 * temp;
System.out.println(pi);
}

分析

大量线程上下文切换

Java 代码

public static void main(String[] args) {
// 大量线程 2000 同时并发,且进行等待
for (int i = 0; i < 2000; i++) {
new Thread(() -> {
try {
work();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
System.out.println(1111111111);

}

private static void work() throws InterruptedException {
Thread.sleep(10000L);
System.out.println("----> do work now");
}

分析

类似上述案例一样,运行程序后,会发现 CPU 突然飙升~~~

总结

命令 汇总

top -Hp [pid]

printf "%x \n" [tid]

jstack [pid]|grep [16 进制 tid] -A 10

posted @ 2019-03-21 16:26  流水青衫  阅读(899)  评论(1)    收藏  举报