线上Java程序占用CPU过高解决方案

 更新时间:2020年11月17日 09:10:07   作者:风的姿态  
这篇文章主要介绍了线上Java程序占用CPU过高解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

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

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

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

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

模拟一个高 CPU 场景

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

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 进程的线程栈保存下来。

jstack 13731 > thread_stack.log

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

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

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • JSON.toJSONString使用异常分析

    JSON.toJSONString使用异常分析

    这篇文章主要为大家介绍了JSON.toJSONString使用异常分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • Java刷视频浏览量点赞量的实现代码

    Java刷视频浏览量点赞量的实现代码

    这篇文章主要介绍了Java刷视频浏览量点赞量的实现代码,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-04-04
  • Mybatis使用注解实现复杂动态SQL的方法详解

    Mybatis使用注解实现复杂动态SQL的方法详解

    当使用 MyBatis 注解方式执行复杂 SQL 时,你可以使用 @Select、@Update、@Insert、@Delete 注解直接在接口方法上编写 SQL,本文给大家介绍了Mybatis如何使用注解实现复杂动态SQL,文中有相关的代码示例供大家参考,需要的朋友可以参考下
    2023-12-12
  • Java获取UTC时间的方法详解

    Java获取UTC时间的方法详解

    这篇文章主要介绍了Java获取UTC时间的方法,结合具体实例形式详细分析了Java针对时区、本地时间、时间偏移量等相关操作技巧,需要的朋友可以参考下
    2017-04-04
  • SpringBoot整合微信登录功能的实现方案

    SpringBoot整合微信登录功能的实现方案

    今天通过本文给大家分享微信登录与SpringBoot整合过程,微信扫描登录实现代码知道扫描后点击登录的全部过程,本文给大家介绍的非常详细,需要的朋友可以参考下
    2021-10-10
  • java内部类使用总结

    java内部类使用总结

    本文主要介绍了java内部类使用总结。具有很好的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • SpringBoot+ShardingSphereJDBC实现读写分离详情

    SpringBoot+ShardingSphereJDBC实现读写分离详情

    这篇文章主要介绍了SpringBoot+ShardingSphereJDBC实现读写分离详情,通过用​​MySQL​​进行一主一从的主从复制展开全文内容,需要的朋友可以参考一下
    2022-08-08
  • mybatis查询数据赋值到model里面为空的解决

    mybatis查询数据赋值到model里面为空的解决

    这篇文章主要介绍了mybatis查询数据赋值到model里面为空的解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • 基于mybatis like %%的问题

    基于mybatis like %%的问题

    这篇文章主要介绍了mybatis like %%的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • Java应用打包后运行需要注意编码问题

    Java应用打包后运行需要注意编码问题

    这篇文章主要介绍了 Java应用打包后运行需要注意编码问题的相关资料,需要的朋友可以参考下
    2016-12-12

最新评论