三步排查JVM cpu 100%问题
@
本文将通过一个简单的案例,展示几下几点:
如何定位是哪个服务进程导致CPU过载
哪个线程导致CPU过载
哪段代码导致CPU过载
首先是写一个死循环的代码demo,用于模拟cpu100%的场景(此处不一定达到100%,只是为了演示排查过程尽量模拟)
public class BusyCpu {
public static void main(String[] args) {
new Thread() {
@Override
public void run() {
int result = 0;
while (true) {
result++;
if (result > Integer.MAX_VALUE / 2) {
result = 0;
}
System.out.println(result);
}
}
}.start();
}
}
详细步骤
1. 定位哪个服务导致的cpu满载
方法:
- 执行
top -c
,显示进程运行信息列表 - 键入
P (大写p)
,进程按照CPU使用率排序
2. 定位哪个线程导致的cpu满载
上面已经找到最耗cpu的进程,在此基础上,可以寻找耗cpu的线程
方法:
top -Hp 187968
,显示指定进程的线程运行信息列表- 键入
P (大写p)
,线程按照CPU使用率排序
从上图看出,进程187968中最耗cpu的线程是187990
3. 查看堆栈,定位到具体代码段
上面已经找到具体的线程,接下来可以通过在堆栈信息中,查看具体的代码段和相关信息。
首先:
上面线程号是10进制,在堆栈信息中,线程号是16进制,因此可以先通过命令转换为16进制
> printf "%x\n" 187990
2de56
其次方法:
找到进程中的堆栈信息,然后按照线程号查找相关信息
- 打印进程堆栈
- 通过线程id(16进制),过滤得到线程堆栈
> jstack 187968 > temp.stack
github地址:https://github.com/ValjeanShaw
--------
csdn地址: https://blog.csdn.net/im_xiao/