怎么排查CPU飙升

商务办公
线上有些系统,本来跑的好好的,突然有一天就会出现报警,CPU使用率飙升,然后重启之后就好了。例如,多线程操作一个线程不安全的list往往就会出现这种现象。

 [[345730]]

怎么排查CPU飙升

线上有些系统,本来跑的好好的,突然有一天就会出现报警,CPU使用率飙升,然后重启之后就好了。例如,多线程操作一个线程不安全的list往往就会出现这种现象。那么怎么定位到具体的代码范围呢?今天笔者就教大家一个小技巧

代码准备

这次,笔者准备了一个demo代码,大致线程模型是这样的:

 

代码下所示:

  1. public class CpuHighExample { 
  2.  
  3.     public static void cpuHigh() { 
  4.         final List<String> list = new LinkedList<>(); 
  5.         Thread thread1 = new Thread(new Runnable() { 
  6.             @Override 
  7.             public void run() { 
  8.                 int count = 1; 
  9.                 while (true) { 
  10.                     // 构造thread1为消耗很高cpu的线程 
  11.                     count = count + 1; 
  12.                 } 
  13.             } 
  14.         }); 
  15.         thread1.setName("thread1"); 
  16.         Thread thread2 = new Thread(new Runnable() { 
  17.             @Override 
  18.             public void run() { 
  19.                 while (true) { 
  20.                     try { 
  21.                         // 构造thread2为消耗很低cpu的线程 
  22.                         Thread.sleep(1000); 
  23.                     } catch (InterruptedException e) { 
  24.                         e.printStackTrace(); 
  25.                     } 
  26.                 } 
  27.             } 
  28.         }); 
  29.         thread2.setName("thread2"); 
  30.         thread1.start(); 
  31.         thread2.start(); 
  32.     } 

案例运行

这个案例一运行,就听见笔者的电脑风扇起飞了,呼呼作响。直接top一下

 

果然是java进程,占用最高,CPU 100%了(占用了一个核),而其PID是2717,正是我们跑的例子。那么下一步,我们就需要定位到底是那一个线程在耗CPU

  1. top -H 
  2. Threads toggle 
  3.             Starts top with the last remembered ’H’ state reversed.  When this 
  4.             toggle  is  On,  all individual threads will be displayed.  Other- 
  5.             wise, top displays a summation of all threads in a process. 

如man文档所描述,top -H可以打印出线程信息,我们就top -H一下。

 

图中可以看到,占用最高的线程PID是2727,同时线程名是thread1。

继续jstack

我们知道jstack可以dump出jvm所有线程运行的快照,然后我们就可以通过刚才获取的PID去定位到jstack那个进程。

  1. // 注意,这边用top出来的进程号2717,而不是top -H出来的2727 
  2. jstack 2717 > 1.txt 

由于jstack打印出的线程号是以16进制的形式表现的,所以我们对2727的线程号做一次转换,得到aa7。

 

然后我们在1.txt中搜索2727,这里用的是less然后进去后搜索,而不是用grep。因为这样比较直观的能看出之前和之后的信息。less下

 

我们找到aa7后,就直接能发现代码一直跑在CpuHighExample.java第19行上面。

 

当然了,我们需要多jstack几次,如果每次jstack出来都刚好在这段代码左右,那么基本可以证明,是这段代码导致CPU飙升了。

总结

CPU突然飙升这个问题,我们很容易通过top -H和jstack找到对应的代码范围,这无疑极大的缩小了我们的定位范围。

本文转载自微信公众号「 解Bug之路」,可以通过以下二维码关注。转载本文请联系 解Bug之路公众号。

 

责任编辑:武晓燕 来源: 解Bug之路
相关推荐

2023-03-06 08:41:32

CPU使用率排查

2020-11-02 09:25:33

CPUJava线程

2018-08-17 08:44:37

服务器内存排查

2024-05-07 09:04:39

2023-12-26 11:39:50

CPU系统进程

2022-08-08 09:02:23

CPUID日志

2019-11-06 09:36:16

服务器CPUTomcat

2020-09-29 07:59:22

CPU系统性能

2018-11-26 08:49:42

CPU排查负载

2024-05-24 10:15:36

2019-04-29 14:23:46

Java服务器CPU

2010-08-18 09:52:25

Memcache

2022-09-26 23:36:33

Linux系统CPU

2022-04-25 11:27:34

LinuxCPU

2023-07-06 08:02:18

缓存架构操作系统

2019-01-21 11:17:13

CPU优化定位

2024-06-28 11:54:20

2019-07-16 06:43:18

LinuxCPU占用率

2020-10-16 08:10:41

Linux CPU 开发

2020-05-09 13:49:00

内存空间垃圾
点赞
收藏

51CTO技术栈公众号