【三板斧】Java定位CPU使用高問題
1、TOP命令,查詢消耗CPU高的進程號 PID,並記錄下來,按下鍵盤"H"鍵,記錄高消耗線程號,並將改線程號轉換為十六進制
2、使用 jstack [pid] > xx.log 命令打印進程信息,為了定位准確,可以多來幾次
3、打開日志文件,找到十六進制的線程信息,可定位到具體類的某一行。
演示:
1、查詢消耗CPU高的進程號 PID,並記錄下來
#top
top - 18:45:29 up 14 days, 23:27, 6 users, load average: 3.18, 3.08, 2.64
Tasks: 299 total, 1 running, 297 sleeping, 0 stopped, 1 zombie
Cpu(s): 25.7%us, 1.2%sy, 0.3%ni, 72.6%id, 0.1%wa, 0.1%hi, 0.1%si, 0.0%st
Mem: 23641M total, 23388M used, 252M free, 261M buffers
Swap: 24583M total, 0M used, 24583M free, 12252M cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
16511 icore 20 0 3075m 657m 17m S 201 2.8 2859:27 java
8369 root 20 0 207m 7556 2892 S 3 0.0 798:30.19 runHpiAlarm
22123 load 21 1 92800 19m 8332 S 3 0.1 0:59.40 mdrv
最耗CPU的進程號16511
按下鍵盤"H"鍵,記錄高消耗線程號,並將改線程號轉換為十六進制
top - 18:46:25 up 14 days, 23:28, 6 users, load average: 3.10, 3.06, 2.66
Tasks: 2722 total, 4 running, 2717 sleeping, 0 stopped, 1 zombie
Cpu(s): 26.0%us, 1.4%sy, 0.4%ni, 71.4%id, 0.8%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 23641M total, 23395M used, 245M free, 261M buffers
Swap: 24583M total, 0M used, 24583M free, 12256M cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
19691 icore 20 0 3075m 657m 17m R 100 2.8 1419:59 java
19690 icore 20 0 3075m 657m 17m R 100 2.8 1419:58 java
8370 root 20 0 207m 7556 2892 S 2 0.0 497:56.23 runHpiAlarm
8408 root 20 0 207m 7556 2892 S 1 0.0 299:23.67 runHpiAlarm
線程號:19691 、19690 轉換為十六進制為:0x4ceb 、0x4cea
2、使用 jstack [pid] > xx.log 命令打印進程信息
#jstack 16511 > 1.log
#jstack 16511 > 2.log
#jstack 16511 > 3.log
3、打開日志文件,找到兩個線程信息,如下
"Thread-77" prio=10 tid=0x00007f58d4041800 nid=0x4ceb runnable [0x00007f58d175f000]
java.lang.Thread.State: RUNNABLE
at com.huawei.iiss.upadapter.common.oprindex.thread.OprUserIndexThread.run(OprUserIndexThread.java:61)
at java.lang.Thread.run(Thread.java:662)
"Thread-76" prio=10 tid=0x00007f58d4a43800 nid=0x4cea runnable [0x00007f58bd066000]
java.lang.Thread.State: RUNNABLE
at com.huawei.iiss.upadapter.common.oprlog.thread.SaveOprLogThread.run(SaveOprLogThread.java:80)
at java.lang.Thread.run(Thread.java:662)
找到以上紅色信息,已經定位到JAVA具體代碼,產看代碼,發現死循環。。。速度改之
附:TOP命令中需要關注的值:
(1)load average:此值反映了任務隊列的平均長度;如果此值超過了CPU數量,則表示當前CPU數量不足以處理任務,負載過高
(2)%us:用戶CPU時間百分比;如果此值過高,可能是代碼中存在死循環、或是頻繁GC等
(3)%sy:系統CPU時間百分比;如果此值過高,可能是系統線程競爭激烈,上下文切換過多,應當減少線程數
(4)%wa:等待輸入、輸出CPU時間百分比;如果此值過高,說明系統IO速度過慢,CPU大部分時間都在等待IO完成
(5)%hi:硬件中斷CPU百分比;當硬件中斷發生時,CPU會優先去處理硬件中斷;比如,網卡接收數據會產生硬件中斷
(6)swap used:被使用的swap;此值過高代表系統因為內存不足在進行頻繁的換入、換出操作,這樣會影響效率,應增大內存量
(7)%CPU:進程使用CPU的百分比;此值高表示CPU在進行無阻塞運算等