1.top
定位哪个进程占用cpu最高
#查看当前占用资源最多的进程
$ top
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
40 root 20 0 4289m 874m 13312 S 123.0 10.9 10:39.73 java
PID — 进程id
USER — 进程所有者
PR — 进程优先级
NI — nice值。负值表示高优先级,正值表示低优先级
VIRT — 进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES
RES — 进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA
SHR — 共享内存大小,单位kb
S — 进程状态。D=不可中断的睡眠状态 R=运行 S=睡眠 T=跟踪/停止 Z=僵尸进程
%CPU — 上次更新到现在的CPU时间占用百分比
%MEM — 进程使用的物理内存百分比
TIME+ — 进程使用的CPU时间总计,单位1/100秒
COMMAND — 进程名称(命令名/命令行)
2.top -Hp 40(进程号)
定位该进程下哪个线程占用cpu最高
#查看该进程下的所有线程的cpu使用情况
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
42 root 20 0 4289m 874m 13312 S 112 10.9 3:02.96 java
3.printf %x 42(线程号) 转换16进制
$ printf %x 42
# 2a
4.jstack 进程号 |grep -A 200 16进制线程号
$ jstack 40 |grep -A 200 2a
查看堆栈信息
"BaseDataReader: error stream of fsnotifier64" #44 prio=4 os_prio=0 cpu=0.61ms elapsed=187894.32s tid=0x00007f8a847d3800 nid=0xd214 runnable [0x00007f8a484cf000]
java.lang.Thread.State: RUNNABLE
at java.io.FileInputStream.readBytes(java.base@11.0.7/Native Method)
at java.io.FileInputStream.read(java.base@11.0.7/FileInputStream.java:279)
at java.io.BufferedInputStream.read1(java.base@11.0.7/BufferedInputStream.java:290)
at java.io.BufferedInputStream.read(java.base@11.0.7/BufferedInputStream.java:351)
- locked <0x00000000d88b25b8> (a java.lang.ProcessImpl$ProcessPipeInputStream)
at sun.nio.cs.StreamDecoder.readBytes(java.base@11.0.7/StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(java.base@11.0.7/StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(java.base@11.0.7/StreamDecoder.java:178)
4.总结
使用top指令查看当前占用CPU较高的进程PID;
查看当前进程消耗资源的线程PID: top -Hp PID
将线程PID转为16进制,根据该16进制值去打印的堆栈日志内查询,查看该线程所驻留的方法位置。
通过jstack命令,查看栈信息,这步基本上已经能够定位大多数问题了
死锁,Deadlock(重点关注)
执行中,Runnable
等待资源,Waiting on condition(重点关注)
等待获取监视器,Waiting on monitor entry(重点关注)
对象等待中,Object.wait() 或 TIMED_WAITING
暂停,Suspended
阻塞,Blocked(重点关注)
停止,Parked
不论多少,您的支持就是我创作最大的动力,敬礼