三步排查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使用率排序
image-20200614135219759

从上图看出,进程187968中最耗cpu的线程是187990

3. 查看堆栈,定位到具体代码段

上面已经找到具体的线程,接下来可以通过在堆栈信息中,查看具体的代码段和相关信息。

首先

上面线程号是10进制,在堆栈信息中,线程号是16进制,因此可以先通过命令转换为16进制

> printf "%x\n" 187990

2de56

其次方法

找到进程中的堆栈信息,然后按照线程号查找相关信息

  • 打印进程堆栈
  • 通过线程id(16进制),过滤得到线程堆栈
> jstack 187968 > temp.stack
image-20200614140559262
posted @ 2020-06-14 14:17  南山饱虎  阅读(1309)  评论(0编辑  收藏  举报