Java程序占用 CPU 过高怎么排查

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

[[349805]]

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

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

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

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

模拟一个高 CPU 场景

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

  1. public static void main(String[] args)  { 
  2.   for (int i = 0; i < 10; i++) { 
  3.     Thread thread = new Thread(() -> { 
  4.       System.out.println(Thread.currentThread().getName()); 
  5.       try { 
  6.         Thread.sleep(30 * 60 * 1000); 
  7.       }catch (Exception e){ 
  8.         e.printStackTrace(); 
  9.       } 
  10.     }); 
  11.     thread.setName("thread-" + i); 
  12.     thread.start(); 
  13.   } 
  14.  
  15.   Thread highCpuThread = new Thread(() -> { 
  16.     int i = 0; 
  17.     while (true) { 
  18.       i++; 
  19.     } 
  20.   }); 
  21.   highCpuThread.setName("HighCpu"); 
  22.   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 进程的线程栈保存下来。

  1. jstack 13731 > thread_stack.log 

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

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

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

本文转载自微信公众号「古时的风筝」,可以通过以下二维码关注。转载本文请联系古时的风筝公众号。

 

责任编辑:武晓燕 来源: 古时的风筝
相关推荐

2019-04-29 14:23:46

Java服务器CPU

2017-02-16 19:39:29

Windows 10System进程CPU

2017-02-07 19:02:47

Windows 7WindowsCPU

2021-02-26 13:35:46

JavaCPU内存

2018-11-26 08:49:42

CPU排查负载

2020-10-12 14:18:15

CPU技巧代码

2010-08-18 09:52:25

Memcache

2020-12-20 10:37:06

Windows10操作系统CPU

2022-06-27 11:20:13

工具内存GO

2019-07-16 06:43:18

LinuxCPU占用率

2022-03-11 07:30:04

SQLMySQLCPU

2021-05-12 06:57:03

Windows 10Windows操作系统

2022-08-04 13:58:28

Windows 11微软CPU

2019-07-24 11:52:11

CPU服务器面试官

2023-03-08 10:22:25

NVIDIAWindows

2009-08-13 17:53:59

控制CPU占用率

2023-08-23 07:48:35

2018-08-13 10:45:36

Windows 10WindowsCPU处理器

2021-11-19 11:50:48

MyBatisforeachJava

2021-05-12 21:10:22

Windows10操作系统微软
点赞
收藏

51CTO技术栈公众号