最近比較忙,就簡單寫個隨筆吧。
簡述
對於cpu爆滿問題,常常會分析是否存在問題線程,本文記錄一種通過top快速找到問題線程nid的方式。
找到問題進程PID
通過top
找到問題進程,例如下面有個進程CPU佔用率高達99%,他的PID=270973
。
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
270973 worker 20 0 7166968 1.537g 3684 S 99.0 50.5 86501:25 java
1285003 root 20 0 14.107g 4.651g 5664 S 0 0.4 762:10.25 java
2805995 root 20 0 9.829g 2.587g 4604 S 0 0.1 3061:22 java
找到問題線程PID
通過top -p 270973 -H
查找問題線程。
其中-p 270973
表示查找指定進程270973
的信息,-H
表示線程模式。
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2447223 root 20 0 3819540 1.319g 5960 S 80.3 42.1 121:25.99 ydbot-client
2447225 root 20 0 3819540 1.319g 5960 S 0.3 2.1 27:41.90 ydbot-client
2447230 root 20 0 3819540 1.319g 5960 S 0.3 2.1 27:57.98 ydbot-client
經對比,發現問題線程的PID=2447223
。
將線程PID轉換爲nid
線程的nid
是十六進制的,在linux系統中,通過shell命令printf
將PID
進行轉換:
$ printf 0x%x 2447223
0x255777
其中0x%x
的0x
是固定字符串,%x
是printf的十六進制的轉換類型。
後續分析
後續通過jstack等工具進行分析,例如:
[root@103-17-208-lg-201-k08 services]# jstack -l 11 |grep 0x255777
2019-09-10 16:18:51
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.73-b02 mixed mode):
"Attach Listener" #18769 daemon prio=9 os_prio=0 tid=0x00007f64dc0d4000 nid=0x255777 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"Keep-Alive-Timer" #18768 daemon prio=8 os_prio=0 tid=0x00007f64c83b8000 nid=0x255777 waiting on condition [0x00007f63ec6e7000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at sun.net.www.http.KeepAliveCache.run(KeepAliveCache.java:172)
at java.lang.Thread.run(Thread.java:745)
其他分析不再贅述。