首先来查看一个 top命令给出的信息

java 查看 哪个线程 占用CPU java查看线程运行时间_java 查看 哪个线程 占用CPU


图中有一个java进程占用了CPU执行时间的百分之99,我们到线上也难免会出现这种问题,那么出现这种问题我们该怎么排查呢?

首先我们已经知道了占用CPU执行时间的进程ID,即16578

那么我们可以使用 top H -p pid 和 ps H -eo pid,tid, %cpu pid 这两个命令中任意一个命令来获取这个进程中是哪个线程占用了执行时间,这里我使用 ps H -eo pid,tid,%cpu 16578 这个命令

java 查看 哪个线程 占用CPU java查看线程运行时间_java_02

因为这个命令会出现所有进程的所有线程相关信息,所以我们使用 grep 过滤一下

第一列是进程id 第二列是这个进程中的线程id 第三个就是占用cpu执行时间的百分比了

其中cpu执行时间都被 16588这个线程所占用

接下来的任务就是要找到这个线程的堆栈信息 使用 jstack 这个jdk自带的工具 来看下线程的信息,但是 jstack这个工具输出的线程信息是 十六进制的,而上面我们获取的线程id是十进制的,因为我们要进行转换在 ,linux中 直接使用 printf ‘%x\n’ 要转换的数据

进行转换即可

java 查看 哪个线程 占用CPU java查看线程运行时间_类加载器_03


拿到 40cc

接下来执行 jstack pid | grep -n -A50 -B50 40cc

因为在实际环境中 jstack会打印很多线程的信息,我们不可能一个一个找,所以就用到了 grep 但是 grep默认只显示这个关键字所在的那一行信息 ,-A50 -B50 的意思就是显示关键字所在的那一行的上下文的50行 -n 就是显示行号

java 查看 哪个线程 占用CPU java查看线程运行时间_java_04

这里的信息就很清楚了,我们只找关键信息
很明显这个线程名 thread–1 是我们自己定义的线程,所以找与自己类相关的信息,
接下来去找 TestThread这个类的第 10行附近相关的代码,注意: 是第10行附近,因为有时候不是那么准确,但是也不会相差太远

java 查看 哪个线程 占用CPU java查看线程运行时间_java_05

找到附近代码后,然后去分析代码的问题
这里我只是演示怎么去找,实际生产环境要比这个复杂的多,但是思路基本上一致