问题 - 异常占用大量 CPU 资源排查

23 篇文章 1 订阅
13 篇文章 0 订阅

  一日,收到服务器 CPU 资源占用满的报警,如下,随抓紧排查:

  • top

  首先使用最简单的工具 top 一下,查看是哪个进程占用了大量的 CPU 资源,如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y6PVo6hg-1611714688629)(http://pencil.file.lynchj.com/depend/20210127094718.png)]

  可以看到的是一个 Java 进程把所有的 CPU 资源都给占用掉了,一个完整的 Java 程序是由大量的线程组成的,也就是说进程里面的某一个或多个线程可能占用了大量的 CPU 资源,只需找出它即可。

  • top -Hp <pid>

  使用命令 top -Hp <pid> 即可查看指定 pid 进程下的线程情况,上图查看到这个 Java 进程的 pid 为 1,所以执行 top -Hp 1 得到如下图:

  由上图可见,pid55 的这个线程占用了大量的 CPU 资源。这里已经定位到了在系统中的 pid,接下来要知道的是这个 pid 具体对应的是 Java 中的哪个线程?哪个类?甚至是在哪一行代码?这样才能更好的定位到代码的问题所在。

  • printf "%x\n" <pid>

  使用 printf "%x\n" 55 把上一步中找到的这个 pid 55 转换成十六进制格式。

$ printf "%x\n" 55
37
  • jstack

jstack 是 Java 虚拟机自带的一种堆栈跟踪工具。jstack 用于打印出给定的 Java 进程 IDcore file远程调试服务的 Java 堆栈信息。

  这里使用 jstack 1 来列出 Java 进程的堆栈信息,并删选出来指定线程 37 (上步所得十六进程 pid)的信息。

$ jstack 1 | grep nid=0x37
"general-thread-pool-1" #23 prio=5 os_prio=0 tid=0x00007f4cc08be800 nid=0x37 runnable [0x00007f4c56afd000]

  上一步找到了对应的线程 general-thread-pool-1,但是这个线程具体运行的哪一块的代码还没有找到,继续之。

  • -A 7:把 grep 筛选出来的目标向下延伸指定行。因为命令 jstack 本身就把堆栈信息打出来了,所以只需要把筛选信息多显示一点就可以看到堆栈信息,也就找到是哪里引起的 CPU 异常了。
$ jstack 1 | grep -A 7 nid=0x37
"general-thread-pool-1" #23 prio=5 os_prio=0 tid=0x00007f4cc08be800 nid=0x37 runnable [0x00007f4c56afd000]
   java.lang.Thread.State: RUNNABLE
	at com.lynchj.CollectExecTask.lambda$readyTask$1(CollectExecTask.java:97)
	at com.lynchj.CollectExecTask$$Lambda$837/1786872722.run(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值