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占用过高问题解决