绑定完请刷新页面
取消
刷新

分享好友

×
取消 复制
​高频面试题:Java程序占用 CPU 过高怎么排查
2021-01-15 17:29:35


这个问题可以说是 Java 面试的高频面试题了,有很多面试官都喜欢问这个问题,问题可能是下面这样的。

线上一台服务器 CPU 使用率 了,如果你碰到这样的情况,如何排查并找到问题原因?

这就是一个套路题,所谓套路题就是有标准的套路解法的,掌握了套路,不仅能解决面试官,还能解决问题。不然真的就掉进套路里了。

当我们真碰到这个问题的时候应该怎么排查呢?

模拟一个高 CPU 场景

先用一段程序创建几个线程,将其中一个线程设置成高 CPU 使用率的。

public static void main(String[] args)  {
  for (int i = ; i < 10; i++) {
    Thread thread = new Thread(() -> {
      System.out.println(Thread.currentThread().getName());
      try {
        Thread.sleep(30 * 60 * 1000);
      }catch (Exception e){
        e.printStackTrace();
      }
    });
    thread.setName("thread-" + i);
    thread.start();
  }

  Thread highCpuThread = new Thread(() -> {
    int i = ;
    while (true) {
      i++;
    }
  });
  highCpuThread.setName("HighCpu");
  highCpuThread.start();
}

运行这段程序后,前面 10 个线程都处于休眠状态,只有后一个线程会持续的占用 CPU 。

运行这段程序,然后就可以开始一些列的操作来发现问题原因了。

排查步骤

步,使用 top 找到占用 CPU 高的 Java 进程

在真实环境中,首先要确认是不是 Java 程序造成的,如果有系统监控工具,可能会直接在预警信息里告诉你是有哪个进程造成的,但也有可能不知道,需要我们手动排查。

如果是在面试场景中,这个问题可能不需要确认,毕竟 Java 面试,面试官可能直接就告诉你是 Java 占用的 CPU 过高。

这一步也非常简单,就是一个 top命令而已,基本上所有同学都用过这个命令吧。

使用 top命令发现占用 CPU 99.7% 的线程是 Java 进程,进程 PID 为 13731

第二步,用 top -Hp 命令查看占用 CPU 高的线程

上一步用 top命令找到了那个 Java 进程。那一个进程中有那么多线程,不可能所有线程都一直占着 CPU 不放,这一步要做的就是揪出这个罪魁祸首,当然有可能不止一个。

执行top -Hp pid命令,pid 就是前面的 Java 进程,我这个例子中就是 13731 ,完整命令为:

top -Hp 13731,执行之后的效果如下

可以看到占用 CPU 高的那个线程 PID 为 13756

然后将 13756转换为 16 进制的,后面会用到,可以用在线进制转换的网站直接转换,转换结果为 0x35bc

第三步,保存线程栈信息

当前 Java 程序的所有线程信息都可以通过 jstack命令查看,我们用jstack命令将步找到的 Java 进程的线程栈保存下来。

jstack 13731 > thread_stack.log

第四步,在线程栈中查找贵祸首的线程

第二步已经找到了这个罪魁祸首的线程 PID,并把它转换成了 16 进制的,第三步保存下来的线程栈中有所有线程的 PID 16 进制信息,我们在线程栈中查找这个16进制的线程 id (0x35bc)。

怎么样,现在一目了然了,线程名称、线程状态、以及哪行代码消耗了多的 CPU 都很清楚了。

点赞、在看、分享走一波?


分享好友

分享这个小栈给你的朋友们,一起进步吧。

Java小专栏
创建时间:2019-08-08 21:32:06
Java专栏专注技术分享
展开
订阅须知

• 所有用户可根据关注领域订阅专区或所有专区

• 付费订阅:虚拟交易,一经交易不退款;若特殊情况,可3日内客服咨询

• 专区发布评论属默认订阅所评论专区(除付费小栈外)

栈主、嘉宾

查看更多
  • lihong
    栈主

小栈成员

查看更多
  • 栈栈
  • 杨三百
  • at_1
  • gaokeke123
戳我,来吐槽~