jstack命令查看占用CPU高的线程堆栈信息
1.使用top命令,找到cpu消耗很高的进程pid
1.1查看java进程
语法:top
语法:jps
语法:ps -ef|grep java
例子:
[lhc@localhost hermes]$ top
top - 09:08:47 up 284 days, 15:37, 4 users, load average: 6.31, 6.26, 6.17
Tasks: 311 total, 1 running, 310 sleeping, 0 stopped, 0 zombie
%Cpu(s): 19.5 us, 55.5 sy, 0.0 ni, 25.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 15607.2 total, 4273.9 free, 6819.4 used, 4513.9 buff/cache
MiB Swap: 7964.0 total, 6339.2 free, 1624.8 used. 7647.9 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2676872 root 20 0 7056468 1.1g 17940 S 598.7 7.0 38:00.45 java
1 root 20 0 246244 7824 4528 S 0.0 0.0 16:22.05 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:12.36 kthreadd
3 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 rcu_gp
4 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 rcu_par_gp
6 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 kworker/0:0H-kblockd
9 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 mm_percpu_wq
1.2查看高负载下的高负载线程:
语法:top -H -p
解释: :进程id
例子:
top -H -p 2676872
例如:
[lhc@localhost hermes]$ top -H -p 2676872
top - 09:10:44 up 284 days, 15:39, 4 users, load average: 6.04, 6.17, 6.14
Threads: 52 total, 6 running, 46 sleeping, 0 stopped, 0 zombie
%Cpu(s): 19.9 us, 55.1 sy, 0.0 ni, 24.9 id, 0.0 wa, 0.1 hi, 0.0 si, 0.0 st
MiB Mem : 15607.2 total, 4275.8 free, 6817.4 used, 4514.0 buff/cache
MiB Swap: 7964.0 total, 6339.2 free, 1624.8 used. 7649.9 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2676908 root 20 0 7056468 1.1g 17940 R 99.9 7.0 8:10.29 pool-2-thread-4
2676910 root 20 0 7056468 1.1g 17940 R 99.9 7.0 8:10.49 pool-2-thread-6
2676905 root 20 0 7056468 1.1g 17940 R 99.9 7.0 8:10.18 pool-2-thread-1
2676906 root 20 0 7056468 1.1g 17940 R 99.9 7.0 8:10.13 pool-2-thread-2
2676907 root 20 0 7056468 1.1g 17940 R 99.9 7.0 8:09.87 pool-2-thread-3
2676909 root 20 0 7056468 1.1g 17940 R 99.9 7.0 8:09.68 pool-2-thread-5
2676872 root 20 0 7056468 1.1g 17940 S 0.0 7.0 0:00.00 java
2676874 root 20 0 7056468 1.1g 17940 S 0.0 7.0 0:08.54 java
1.3、将高负载线程号转换成16进制
语法: printf “%x\n”
eg: printf “%x\n” 2676872
例子:
[lhc@localhost hermes]$ printf “%x\n” 2676872
28d888
1.4、然后再使用jstack查询线程的堆栈信息
这里有两种方式:
1.4.1、直接在服务器窗口上通过命令查看:
语法:jstack | grep -a 线程id(十六进制)
eg: jstack 13769 | grep -a 39e5
这样就可以在服务器窗口上直接打印高负载线程的堆栈信息了
1.4.2、将对应进程的堆栈信息都打印出来存到文件中,
然后再在文件中搜索对应的线程号(16进制)进行查看:
语法:jstack -l >> 123.txt
eg: jstack -l 13769 >> 123.txt
a、打印jstack信息到文件(文件会保存在当前目录下)
b、导出进程的堆栈日志文件,找到39e5这个线程号,然后就可以跟踪代码找到对应的问题所在
另外,导出堆栈信息文件的命令中一般有两个运行参数,用来拍取内存快照
他们的含义如下:
-l long listings,会打印出额外的锁信息,在发生死锁时可以用jstack -l pid来观察锁持有情况
-m mixed mode,不仅会输出Java堆栈信息,还会输出C/C++堆栈信息(比如Native方法)
2.实际查看堆栈遇到的问题:
2.1当前进程持有者问题
[lhc@localhost hermes]$ jstack 2676872 | grep -a 28D888
2676872: well-known file /tmp/.java_pid2676872 is not secure: file should be owned by the current user (which is 1003) but is owned by 0
2.2输出堆栈信息没有权限
[lhc@localhost hermes]$ jstack -l 2676909 >> 123.txt
2676909: Operation not permitted
解决方法:更换账号成当前进程持有者账号或者实时root账号再去操作。