1、首先用 ps aux|grep jar包名字 找到进程的PID, 直接top命令也能看到CPU最高的进程PID
2、用 top -Hp 进程PID 获取CPU占用高的线程(下图中PID的1091,1063就是线程ID),网上的文章用 ps -mp 进程PID -o THREAD,tid,time 也可以
Threads: 105 total, 0 running, 105 sleeping, 0 stopped, 0 zombie
%Cpu(s): 1.4 us, 0.8 sy, 0.0 ni, 97.6 id, 0.2 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 32781008 total, 11521252 free, 16629800 used, 4629956 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 15713740 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1091 root 20 0 11.8g 2.8g 14804 S 1.3 9.0 10:26.33 java
1063 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:00.02 java
1064 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:26.79 java
1065 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:01.10 java
1066 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:00.97 java
1067 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:00.98 java
1068 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:00.90 java
1069 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:01.67 java
1070 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:00.03 java
1071 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:00.04 java
1072 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:00.00 java
1073 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:46.23 java
1074 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:46.86 java
1075 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:13.22 java
1076 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:00.00 java
1077 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:18.34 java
1088 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:11.60 java
1089 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:00.42 java
1090 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:00.02 java
1092 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:01.87 java
1105 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:00.72 java
1106 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:00.11 java
1107 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:01.71 java
1108 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:01.75 java
1109 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:01.72 java
1110 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:01.75 java
1111 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:01.73 java
1112 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:01.72 java
1113 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:01.72 java
1114 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:01.72 java
1115 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:01.74 java
1116 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:01.70 java
1117 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:01.74 java
1118 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:01.72 java
1119 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:01.70 java
1120 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:01.71 java
1121 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:01.70 java
1122 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:01.75 java
1123 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:01.72 java
1124 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:01.70 java
1125 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:01.74 java
1126 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:01.71 java
1127 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:00.99 java
1133 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:00.08 java
1134 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:00.10 java
1135 root 20 0 11.8g 2.8g 14804 S 0.0 9.0 0:00.02 java
[root@abc ~]# ps -mp 1063 -o THREAD,tid,time
USER %CPU PRI SCNT WCHAN USER SYSTEM TID TIME
root 1.7 - - - - - - 00:14:52
root 0.0 19 - futex_ - - 1063 00:00:00
root 0.0 19 - futex_ - - 1064 00:00:26
root 0.0 19 - futex_ - - 1065 00:00:01
root 0.0 19 - futex_ - - 1066 00:00:00
root 0.0 19 - futex_ - - 1067 00:00:00
root 0.0 19 - futex_ - - 1068 00:00:00
root 0.0 19 - futex_ - - 1069 00:00:01
root 0.0 19 - futex_ - - 1070 00:00:00
root 0.0 19 - futex_ - - 1071 00:00:00
root 0.0 19 - futex_ - - 1072 00:00:00
root 0.0 19 - futex_ - - 1073 00:00:46
root 0.0 19 - futex_ - - 1074 00:00:46
root 0.0 19 - futex_ - - 1075 00:00:13
root 0.0 19 - futex_ - - 1076 00:00:00
root 0.0 19 - futex_ - - 1077 00:00:18
root 0.0 19 - futex_ - - 1088 00:00:11
root 0.0 19 - futex_ - - 1089 00:00:00
root 0.0 19 - futex_ - - 1090 00:00:00
root 1.2 19 - futex_ - - 1091 00:10:33
root 0.0 19 - futex_ - - 1092 00:00:01
root 0.0 19 - futex_ - - 1105 00:00:00
root 0.0 19 - futex_ - - 1106 00:00:00
root 0.0 19 - futex_ - - 1107 00:00:01
root 0.0 19 - futex_ - - 1108 00:00:01
root 0.0 19 - futex_ - - 1109 00:00:01
root 0.0 19 - futex_ - - 1110 00:00:01
root 0.0 19 - futex_ - - 1111 00:00:01
root 0.0 19 - futex_ - - 1112 00:00:01
root 0.0 19 - futex_ - - 1113 00:00:01
root 0.0 19 - futex_ - - 1114 00:00:01
root 0.0 19 - futex_ - - 1115 00:00:01
root 0.0 19 - futex_ - - 1116 00:00:01
root 0.0 19 - futex_ - - 1117 00:00:01
root 0.0 19 - futex_ - - 1118 00:00:01
root 0.0 19 - futex_ - - 1119 00:00:01
root 0.0 19 - futex_ - - 1120 00:00:01
root 0.0 19 - futex_ - - 1121 00:00:01
root 0.0 19 - futex_ - - 1122 00:00:01
root 0.0 19 - futex_ - - 1123 00:00:01
root 0.0 19 - futex_ - - 1124 00:00:01
root 0.0 19 - futex_ - - 1125 00:00:01
root 0.0 19 - futex_ - - 1126 00:00:01
root 0.0 19 - futex_ - - 1127 00:00:01
root 0.0 19 - sk_wai - - 1133 00:00:00
root 0.0 19 - futex_ - - 1134 00:00:00
root 0.0 19 - futex_ - - 1135 00:00:00
root 0.0 19 - futex_ - - 1136 00:00:00
root 0.0 19 - futex_ - - 1139 00:00:01
root 0.0 19 - futex_ - - 1140 00:00:04
root 0.0 19 - futex_ - - 1141 00:00:00
root 0.0 19 - futex_ - - 1142 00:00:00
root 0.0 19 - ep_pol - - 1143 00:00:05
root 0.0 19 - futex_ - - 1144 00:00:00
root 0.0 19 - futex_ - - 1146 00:00:01
root 0.0 19 - futex_ - - 1148 00:00:00
root 0.0 19 - futex_ - - 1149 00:00:00
root 0.0 19 - futex_ - - 1153 00:00:00
root 0.0 19 - futex_ - - 1154 00:00:00
root 0.0 19 - futex_ - - 1155 00:00:02
root 0.0 19 - futex_ - - 1156 00:00:00
root 0.0 19 - futex_ - - 1157 00:00:00
root 0.0 19 - futex_ - - 1158 00:00:00
root 0.0 19 - ep_pol - - 1162 00:00:01
root 0.0 19 - futex_ - - 1163 00:00:01
3、用计算器把线程ID转换为16进制, 网上的文章用 printf "%x\n" 线程ID 也能输出16进制的值
4、 把进程每个线程的堆栈输出到文件, jstack 进程PID >> ABC.TXT
5、 在ABC.TXT文件中查找 16进制的线程ID,找到后查看自己代码的包名,比如像下面这样的包名, java.util或者com.alibaba之类的肯定不会有问题了, 找其他属于自己写的代码的包即可。
"System Clock" #17 daemon prio=5 os_prio=0 tid=0x00007fe5b58c0000 nid=0xd108 runnable [0x00007fe54a425000]
java.lang.Thread.State: RUNNABLE
at java.util.concurrent.ScheduledThreadPoolExecutor.reExecutePeriodic(ScheduledThreadPoolExecutor.java:346)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:296)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
"Druid-ConnectionPool-Destroy-389247924" #16 daemon prio=5 os_prio=0 tid=0x00007fe5b606e800 nid=0xd106 runnable [0x00007fe54abdd000]
java.lang.Thread.State: RUNNABLE
at java.lang.Long.valueOf(Long.java:840)
at com.alibaba.druid.filter.stat.StatFilter.connection_close(StatFilter.java:255)
at com.alibaba.druid.filter.FilterChainImpl.connection_close(FilterChainImpl.java:181)
at com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl.close(ConnectionProxyImpl.java:115)
at com.alibaba.druid.util.JdbcUtils.close(JdbcUtils.java:73)
at com.alibaba.druid.pool.DruidDataSource.shrink(DruidDataSource.java:2797)
at com.alibaba.druid.pool.DruidDataSource$DestroyTask.run(DruidDataSource.java:2562)
at com.alibaba.druid.pool.DruidDataSource$DestroyConnectionThread.run(DruidDataSource.java:2549)
5、如果你搜索CPU高的线程,搜到如下的线程,那也是你的代码有问题,系统内存不够,启动了垃圾回收,然后你的代码又拼命的分配内存就会造成GC线程CPU占用过高,这个时候, 你自己包名的线程CPU不一定高,继续查找执行自己代码的线程,看看他们在执行哪些代码,这些代码应该就是有问题的代码了。
"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007fe5b4020800 nid=0xd0ec runnable
"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007fe5b4022800 nid=0xd0ed runnable
"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00007fe5b4024800 nid=0xd0ee runnable
"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00007fe5b4026000 nid=0xd0ef runnable