linux某一个进程80%问题分析过程

tech2023-06-30  110

linux某一个进程80%问题分析过程

该文章主要内容1.CPU排查三部曲1.1 top命令查看耗费CPU最高的进程1.2 top -H -p $pid 找到最耗CPU的线程1.3 使用printf转换线程29798,29824为十六进制值1.4 将dump日志放入6792.txt中1.5 查看dump文件1.5.1 使用jstack 29769 | grep 7480命令快捷搜索日志1.5.2 使用vi命令查看具体日志1.5.3 在vi命令模式下输入/7480,搜索线程号数据 2 报错Unable to open socket file: target process not responding or HotSpot VM not loaded解决2.1 原因分析2.2 jstack报错原因2.3 解决方案:2.4 发现是kafka用户启动的程序. 所以下面以kafka用户身份去执行jmap的dump操作.

该文章主要内容

1.CPU排查三部曲

top找到最耗cpu的进程top -H -p $pid 找到最耗CPU的线程.将最耗CPU的线程ID转成16进制打印jstack, 到jstack里面查这个线程在干嘛

当然 如果你线上环境有装arthas等工具的话, 直接thread -n就可以打印出最耗cpu的n个线程的堆栈,三个步骤一起帮你做了.

1.1 top命令查看耗费CPU最高的进程

[root@wisdomroad ~]# top

top命令查看最耗cpu的进程

可以看到6792这个进程占用cpu达到88%,这里需要解释一下,同样的应用在win机器上可能只占用20%的cpu,为什么会有如此大的差别,因为linux计算CPU耗费是以一个cpu为单位计算的,而windows计算是以所有cpu数量*20%计算的,所以理论上两者耗费CPU差不多,甚至windows算下来会更多

1.2 top -H -p $pid 找到最耗CPU的线程

[root@wisdomroad ~]# top -H-p 29769

可以看出进程29769有两个线程29798和29824耗费CPU达到40%

1.3 使用printf转换线程29798,29824为十六进制值

[root@wisdomroad ~]# printf "%x\n" 29798 7644 [root@wisdomroad ~]# printf "%x\n" 29824 7480

1.4 将dump日志放入6792.txt中

将该进程的全部堆栈信息放入临时文件29769.txt里面

[root@wisdomroad ~]# jstack 29769 > /tmp/29769.txt

1.5 查看dump文件

1.5.1 使用jstack 29769 | grep 7480命令快捷搜索日志

[root@wisdomroad ~]# jstack 29769 | grep 7466 "MQTT Call: paho22423893051402" #23 prio=5 os_prio=0 tid=0x00007f9463437800 nid=0x7466 runnable [0x00007f9440b55000] [root@wisdomroad ~]# jstack 29769 | grep 7480 "MQTT Call: paho22423893051402" #47 prio=5 os_prio=0 tid=0x00007f93ec078000 nid=0x7480 in Object.wait() [0x00007f9424cc6000] [root@wisdomroad ~]#

可以看出这两个一个是在runnable中,一个在Object.wait()

1.5.2 使用vi命令查看具体日志

[root@wisdomroad ~]# vi /tmp/29769.txt

1.5.3 在vi命令模式下输入/7480,搜索线程号数据

最后看到搜索结果,光标闪烁在Object.wait这一行。nid就是之前printf 命令打印的进程号

这个线程正在等待条件满足,触发之后的程序执行

2 报错Unable to open socket file: target process not responding or HotSpot VM not loaded解决

6792: Unable to open socket file: target process not responding or HotSpot VM not loaded The -F option can be used when the target process is not responding

2.1 原因分析

jvm运行时会生成一个目录hsperfdata_ U S E R ( USER( USER(USER是启动java进程的用户),在linux中默认是/tmp。目录下会有些pid文件,存放jvm进程信息。

jps、jstack等工具读取/tmp/hsperfdata_$USER下的pid文件获取连接信息。

2.2 jstack报错原因

jstack报错:Unable to open socket file。是因为这个java进程的pid文件删除了。

为什么会被删除呢?这是因为linux操作系统为了防止/tmp目录文件过多,有个删除管理机制:tmpwatch。

2.3 解决方案:

(但是本人试过还是包同样的错误target process not responding or HotSpot VM not loaded) 在网上找到原因: 使用jmap dump 堆内存的时候, 要使用运行这个程序的用户去dump, 其他用户不可以的.

所以刚刚那个命令应该是这样的:

[root@node03 ~]# ps -ef| grep 9017 kafka 9017 1 0 Feb12 ? 02:38:07 /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.181-3.b13.el7_5.x86_64/jre/bin/javaxxxxxxxxxx

2.4 发现是kafka用户启动的程序. 所以下面以kafka用户身份去执行jmap的dump操作.

[root@node03 ~]# sudo -u kafka jmap -dump:format=b,file=heap.hprof 9017

标个重点: sudo -u [user] jmap -dump:format=b,file=heap.hprof [pid]

这里的-dump:format=b,file=heap.hprof可以换成jmap的其他命令, 比如: sudo -u [user] jmap -histo [pid]

具体可参考: jmap、jstack、jps无法连接jvm解决办法 dump堆内存时遇到的异常 : Unable to open socket file: target process not responding or HotSpot VM not loaded Running jmap getting Unable to open socket file

参考文章: java中WAITING状态的线程为啥还会消耗CPU linux查看某进程CPU内存消耗占用最高的线程名称 linux 查看服务器性能常用命令 JVM调优之jstack找出最耗cpu的线程并定位代码 jmap、jstack、jps无法连接jvm解决办法 Linux主机下 java项目CPU占用过高分析jstack可以定位到线程堆栈,根据堆栈信息我们可以定位到具体代码 Java进程cpu占用过高问题解决

最新回复(0)