一种CPU占用过高的故障定位分析方法

目 录

1.前 言

2. 测试类编写

3. 故障定位方法

   3.1 定位CPU占比最高的PID

   3.2 定位该PID对应的应用程序名字

   3.3 定位具体的线程ID

   3.4 定位具体的应用程序代码位置

4. 小结


1.前言

     CPU占用过高是LINUX服务器常见的一种故障,也是程序员线上排查故障必备的技能,如果线上出现此种故障,程序员应如何快速定位代码块排查故障呢?本文将从四个步骤进行分析,快速定位问题所在,从应用程序的进程入手到具体线程再到应用程序的具体代码,从整体到局部,化繁为简,层层深入,为读者提供了一种线上快速定位排查故障的思路和手段。

2. 测试类编写

      编写测试类,模拟占用CPU过高的程序,具体程序代码如下:

public class TopTest {

        public static void main(String[] args) {
            while (true) {

                System.out.println(new java.util.Random().nextInt(777778888));
            }
        }


}

      maven打包后上传至linux服务器中

     运行该JAVA程序

nohup java -jar JavaDemo-1.0-SNAPSHOT.jar >/tmp/TopTest.log  2>&1 ;

     监控日志文件:

[root@bigdata3 tmp]# tail -f TopTest.log

     具体内容如下:

3. 故障定位方法

   3.1 定位CPU占比最高的PID

          先用top命令找出CPU占比最高的PID

             命令行输入 top。其内容如下:

        注:通过shift +h可以锁定哪个进程消耗的CPU高。

        由该图可以看到

  •      (1)平均负载(load average):1.36.说明平均负载过高(超过0.6) ,后台一定有个占用cpu过高的程序。
  •      (2)该程序为一个java程序占用CPU百分比为100.3,内存为0.5%,该java进程ID为11911

  3.2 定位该PID对应的应用程序名字

     ps -ef 或者jps进一步定位得知其具体的后台应用程序名字

ps -ef | grep 11911 | grep -v grep

jps -l

    可以得出该应用程序为:JavaDemo-1.0-SNAPSHOT.jar

 3.3 定位具体的线程ID

   ps -mp 进程ID -o THREAD,tid,time

[root@bigdata3 ~]# ps -mp 11911 -o THREAD,tid,time
USER     %CPU PRI SCNT WCHAN  USER SYSTEM   TID     TIME
root     99.9   -    - -         -      -     - 00:33:35
root      0.0  19    - futex_    -      - 11911 00:00:00
root     99.6  19    - -         -      - 11912 00:33:28
root      0.0  19    - futex_    -      - 11913 00:00:00
root      0.0  19    - futex_    -      - 11914 00:00:00
root      0.0  19    - futex_    -      - 11915 00:00:00
root      0.0  19    - futex_    -      - 11916 00:00:00
root      0.0  19    - futex_    -      - 11917 00:00:00
root      0.0  19    - futex_    -      - 11918 00:00:00
root      0.0  19    - futex_    -      - 11919 00:00:00
root      0.0  19    - futex_    -      - 11920 00:00:00
root      0.0  19    - futex_    -      - 11921 00:00:01
root      0.0  19    - futex_    -      - 11922 00:00:00
root      0.0  19    - futex_    -      - 11923 00:00:00
root      0.0  19    - futex_    -      - 11924 00:00:00
root      0.0  19    - futex_    -      - 11925 00:00:00
root      0.0  19    - futex_    -      - 11926 00:00:00
root      0.0  19    - futex_    -      - 11927 00:00:00
root      0.0  19    - futex_    -      - 11928 00:00:00
root      0.0  19    - futex_    -      - 11929 00:00:00
root      0.0  19    - futex_    -      - 11930 00:00:00

    可以看出有问题的线程为:

     root     99.6  19    - -         -      - 11912 00:33:28

    说明线程TID:11912占用率最高。

    参数解释:

  •    -m:显示所有的线程
  •    -p:pid进程使用CPU的时间
  •    -o:该参数后是用户自定义格式。

  如:THREAD,tid,time表示线程、线程ID号、线程占用的时间

 3.4 定位具体的应用程序代码位置

   解释:定位线程中具体哪一行代码出问题

   (1)将需要的线程ID转换成16进制格式

               1) printf "%x\n" 有问题的线程ID

                     printf "%x\n" 11912

               2)采用计算器计算:

               线程ID11912转换为16进制为:2E88‬->2e88(注意要转换成小写形式)

   (2)jstack进程ID | grep tid(16进制线程ID小写英文)-A60

                jstack 11911 | grep tid(16进制线程ID小写英文) -A60

jstack 11911 | grep 2e88 -A60

  执行结果如下:

"main" #1 prio=5 os_prio=0 tid=0x00007f73f4008800 nid=0x2e88 runnable [0x00007f73fa74f000]
   java.lang.Thread.State: RUNNABLE
	at java.io.FileOutputStream.writeBytes(Native Method)
	at java.io.FileOutputStream.write(FileOutputStream.java:326)
	at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
	at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
	- locked <0x0000000643403bf0> (a java.io.BufferedOutputStream)
	at java.io.PrintStream.write(PrintStream.java:482)
	- locked <0x00000006434030a8> (a java.io.PrintStream)
	at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
	at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
	at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:104)
	- locked <0x0000000643403060> (a java.io.OutputStreamWriter)
	at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:185)
	at java.io.PrintStream.write(PrintStream.java:527)
	- eliminated <0x00000006434030a8> (a java.io.PrintStream)
	at java.io.PrintStream.print(PrintStream.java:597)
	at java.io.PrintStream.println(PrintStream.java:736)
	- locked <0x00000006434030a8> (a java.io.PrintStream)
	at TopTest.main(TopTest.java:6)

"VM Thread" os_prio=0 tid=0x00007f73f41c6000 nid=0x2e91 runnable 

"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007f73f401d800 nid=0x2e89 runnable 

"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007f73f401f800 nid=0x2e8a runnable 

"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00007f73f4021800 nid=0x2e8b runnable 

"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00007f73f4023000 nid=0x2e8c runnable 

"GC task thread#4 (ParallelGC)" os_prio=0 tid=0x00007f73f4025000 nid=0x2e8d runnable 

"GC task thread#5 (ParallelGC)" os_prio=0 tid=0x00007f73f4027000 nid=0x2e8e runnable 

"GC task thread#6 (ParallelGC)" os_prio=0 tid=0x00007f73f4028800 nid=0x2e8f runnable 

"GC task thread#7 (ParallelGC)" os_prio=0 tid=0x00007f73f402a800 nid=0x2e90 runnable 

"VM Periodic Task Thread" os_prio=0 tid=0x00007f73f421c000 nid=0x2e9a waiting on condition 

JNI global references: 9

  可以看出是在TopTest类中main方法的第六行出现问题。

at TopTest.main(TopTest.java:6)

 可以具体定位到代码块如下图所示:第六行

 注:可以通过pwdx +进程ID 找到业务进程路径

4. 小结

    本文阐述了一种CPU占用过高的故障定位方法及思路,文中采用四步分析法进行排查和定位,旨在提供一种快速解决线上CPU占用过高故障的定位方法和思路,通过该方法可以巧妙快速地排查故障,为线上排查故障节省了时间。

欢迎关注石榴姐公众号"我的SQL呀",关注我不迷路

 

  • 213
    点赞
  • 686
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
引用\[1\]:根据引用\[1\]中的信息,定位和分析CPU和内存占用过高的问题可以采取以下步骤: 1. 使用top命令来查找CPU占比最高的进程。这可以帮助我们确定哪个进程正在消耗大量的CPU资源。 2. 使用ps -ef或者jps命令进一步定位该进程,以了解它是什么类型的后台程序。这可以帮助我们确定是哪个程序导致了CPU占用过高的问题。 3. 使用mpstat命令来查看CPU的统计信息,包括每个CPU的状况。这可以帮助我们了解每个CPU的负载情况,以及是否有某个特定的CPU占用过高。 4. 分析收集到的数据,比较CPU占用过高的进程和CPU的负载情况,以确定是否存在异常情况。可以通过比较不同时间段的数据来查看CPU占用是否持续高位。 5. 如果发现某个进程持续占用过高CPU资源,可以进一步分析该进程的代码和逻辑,以确定是否存在性能问题或者优化的空间。 6. 对于内存占用过高的问题,可以使用类似的方法来定位和分析。可以使用top命令查找内存占用最高的进程,使用ps命令定位该进程,然后分析该进程的内存使用情况。 综上所述,通过使用top、ps、mpstat等命令,结合分析收集到的数据,可以定位和分析CPU和内存占用过高的问题。 #### 引用[.reference_title] - *1* *3* [Linux命令及CPU占用过高定位分析思路](https://blog.csdn.net/inexaustible/article/details/129185272)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [一种CPU占用过高故障定位分析方法](https://blog.csdn.net/godlovedaniel/article/details/104735170)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值