java 应用 cpu 过高故障排查

文章目录

        • 一、前言
        • 二、测试代码 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 的情况
在这里插入图片描述


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部