文章目录
- 一、前言
- 二、测试代码 Test.java
- 三、Linux 编译运行 Test.java 程序
- 四、top 命令查看 cpu 使用情况
- 五、查看进程下的线程详情 `top -H -p 11748`
- 六、将`线程` 12240 的 pid 转为 16 进制 ` printf "0x%x\n" 12240`
- 七、jstack 查看`进程`的快照
- 遗留
一、前言
前两天写了一个订阅消息队列程序传递到 Flink,将订阅到的每个数据添加到 Queue 队列中,使用了 while(true) 从消息队列取数据,程序能正常运行,后来发现 CPU 使用率过高,通过排查发现时 while(true) 引起的,现在模拟 cpu 过高排查过程。
二、测试代码 Test.java
public class Test {
public static void main(String[] args) {
System.out.println("测试死循环对 CPU 影响");
for (int i = 0; i < Integer.parseInt(args[0]); i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName());
while (true){
}
},"线程:"+i).start();
}
}
}
三、Linux 编译运行 Test.java 程序
javac Test.java
运行 Test 程序,启动 1 个死循环线程
四、top 命令查看 cpu 使用情况
按大写 C 可以按 CPU 从大到小排序
可以看到 Test 的 CPU 使用率 100%,和 window 区别很大(window CPU 100% 就卡死了),我的 Linux 服务器是 2 核的,总 CPU 使用率 50 %,服务器也不会卡,简单理解就是把一个核跑满了
五、查看进程下的线程详情 top -H -p 11748
如下可以看到进程
12227 下线程
12240 的 CPU 占用最多 99.9%
六、将线程
12240 的 pid 转为 16 进制 printf "0x%x\n" 12240
这一步的目的是从进程快照中检索线程
七、jstack 查看进程
的快照
使用 java jdk 下自带的 jstack 查看进程
的快照 jstack 12227|grep -A 20 0x2fd0
可以看到第 7 行代码引起的,从源代码可以看到是 while(true) 引起的,简单说一下 grep 参数
-
grep -A n 显示匹配指定内容及之后的 n 行
-
grep -B n 显示匹配指定内容及之前的 n 行
-
grep -C n 显示匹配指定内容及其前后各 n 行
输出整个进程
的快照到文件 jstack 12227 >> jstack.log
遗留
当我把线程数量设为 2,发现 2 核 CPU 直接 100%,但云服务器并没有卡死
对于 Linux ,当我把线程数量设为大于 2 的数时,CPU接近 200%,应该只是会影响执行效率,不会导致系统卡死(猜的,操作系统知识都忘完了,等后面了解了再记录),下main是线程数量为 5 的情况