查找cpu占用率最高的java线程
本文讲的是:在 linux 环境下,定位 cpu 使用率最高的 java 线程,找出对应代码的方法。基本思路是:使用 top
命令找出 cpu 占用率最高的 java 线程,然后结合 jstack
定位问题代码。
测试代码
下面是一段测试代码:在 main
方法中启动一个名字为 busyThread
的线程,该线程执行了一个无意义的死循环,用来占用 cpu 资源。
1 | public class Top { |
使用 javac
命令编译为字节码,然后使用 java
命令执行。此时 busyThread
线程会几乎将 cpu 占满。
查找过程
找出cpu占用率最高的java进程
使用 top
命令查看进程情况,根据 command 列显示的名字判断启动的 java 进程。
- 输入
top
- 依次输入
x
和b
打开高亮模式 - 使用
<
或>
切换排序列,切换到按 cpu 排序
1 | top - 23:33:06 up 25 min, 2 users, load average: 1.00, 0.81, 0.53 |
可以看到 cpu 占用率最高的 java 进程的 ID 为 1283
输出堆栈信息
使用 jstack
命令输出 java 进程当前的堆栈信息,为方便后续分析,将输出重定向到 jstack.txt
文件中。
1 | jstack -l 1283 > jstack.txt |
找出cpu占用率最高的java线程
要分析堆栈信息,需要先找到是哪个线程的 cpu 占用率比较高。再次使用 top 命令,加上 -H
参数开启线程模式,使用 -p
参数指定 java 进程的 ID。
1 | top -H -p 1283 |
切换到高亮模式,按 cpu 排序,找出 cpu 占用率最高的 java 线程。
1 | top - 23:36:11 up 28 min, 2 users, load average: 1.00, 0.92, 0.63 |
可以看到是 PID 为 1292 的 java 线程 cpu 占用率比较高。
定位问题代码
下面就可以分析通过 jstack
命令获取到的堆栈信息,在开始前需要对线程 ID 做下转换。因为堆栈信息里的线程 ID 使用的是十六进制,所以需要把 1292
转换为十六进制。
使用 printf
命令,加上 %x
参数
1 | printf "0x%x\n" 1292 |
输出结果为:
1 | 0x50c |
前面的 0x
及后面的 \n
只是为了使用方便。
打开 jstack.txt
文件,搜索 ID 为 0x50c
的线程,结果如下:
1 | "busyThread" #7 prio=5 os_prio=0 tid=0x761b5000 nid=0x50c runnable [0x6485e000] |
可见线程名为 busyThread
,执行的代码位置是 Top.java
的第 17 行,对应代码是 Busy
里的 i++
- 2019-02-21
Java 线程共有 6 种状态,在任意时刻只能处于其中一种状态,随着代码的执行状态也会发生变化。
- 2019-10-15
本文记录的是一些技术文章,主要是一些官方文档,还有一些不错的博客。