目录
一、前言
在前面的博客 性能监控——cpu使用率过高,该怎么分析?中写到了CPU中
us、wa、sy、si
的数据分析流程。其中us、wa、sy
的数据,针对java
语言,都使用到jsatck分析java进程中的线程的堆栈信息
。这里就给大家详细介绍一下分析的过程、jstack的使用和踩坑记录。
二、踩坑记录
2.1 -bash: jstack: command not found
在使用jstack命令时,
提示命令找不到
。
(1)可以直接通过which java
命令进入bin
目录执行jstack命令即可。(2)如果bin目录中不存在jstack文件,就安装其他版本JDK。
2.2 Unable to open socket file
错误信息:在使用jstack命令中,出现了Unable to open socket file: target process not responding or HotSpot VM not loaded
错误后,按照提示添加了-F
参数后执行,提示Error attaching to process: Doesn't appear to be a HotSpot VM (could not find symbol "gHotSpotVMTypes" in remote process)
分析过程:一开始怀疑是进程对应的用户的问题,但是查看过后发现我并没有该名为1000的用户
。在网上查询相关资料后,说可能是Docker容器的问题
,然后根据ps -ef|grep java
命令后显示的信息,我进入了我的Jenkins容器内部,再次使用ps -ef|grep java
查看到对应的java进程,再次使用jstack命令就可以了。
总结:如果该java进程是在Docker容器中运行的,需要进入Docker容器中使用jstack命令。
2.3 Can’t attach to the process
还有一种错误信息,虽然我没遇到该问题,但是在查阅相关资料的时候,经常发现,所以特此记录。出现Can't attach to the process
错误提示后执行下面命令。
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
参考链接:使用Java监控工具出现 Can’t attach to the process
三、jstack使用流程
由于演示的服务器中仅有的java进程是Jenkins容器中使用到,所以就进入Jenkins的Docker容器中演示。
- (1)使用
top
命令查看占用CPU高的进程
- (2)使用
top -Hp PID
命令查看进程下的线程使用情况,记录下占用CPU高的线程ID
- (3)使用
printf "%x\n" 线程ID
命令将刚才获取的线程ID转换为16进制。jenkins@fdee8f2fb633:/$ printf "%x\n" 110 6e
- (4)使用
jstack 进程pid | grep 线程pid16进制
,定位到该进程下,指定线程的信息。正常情况下,这里会定位到java的类名或方法名
。jenkins@fdee8f2fb633:/$ jstack 5 |grep 6e "DestroyJavaVM" #22 prio=5 os_prio=0tid=0x00007fb61c00a800 nid=0x6e waiting oncondition [0x0000000000000000]
- 也可以通过
jstack 进程ID
查看进程下所有线程的使用情况,如果要查看对应的线程的数据,通过线程16进制的数据查找即可。
四、dump文件分析
在通过上述相关命令得到相关进程中线程的堆栈数据后,就是对这些数据进行分析。
参考链接:
三个实例演示 Java Thread Dump 日志分析
如何使用jstack分析线程状态