前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >线上Java程序占用 CPU 过高,请说一下排查方法?

线上Java程序占用 CPU 过高,请说一下排查方法?

作者头像
古时的风筝
发布2020-11-11 16:11:14
6180
发布2020-11-11 16:11:14
举报
文章被收录于专栏:古时的风筝古时的风筝

模拟一个高 CPU 场景

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

代码语言:javascript
复制
public static void main(String[] args)  {
  for (int i = 0; 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 = 0;
    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 进程的线程栈保存下来。

代码语言:javascript
复制
jstack 13731 > thread_stack.log

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

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

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-11-06 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 模拟一个高 CPU 场景
  • 排查步骤
    • 第一步,使用 top 找到占用 CPU 最高的 Java 进程
      • 第二步,用 top -Hp 命令查看占用 CPU 最高的线程
        • 第三步,保存线程栈信息
          • 第四步,在线程栈中查找最贵祸首的线程
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档