JVM简单的问题排查-CPU占用高

550 阅读1分钟

CPU占用高

这里简单的介绍一下关于java项目与到CPU占用高的时候需要怎么排查。这里描述的只是简单的操作,有兴趣的同学可以深入研究。

  1. 模拟高cpu场景(例子):
package com.chenfeilong.demo.JVM问题排查;

/**
 * 死循环,模拟高cpu场景
 *
 * @author chenFeiLong
 * @date 2021/05/07 19:20:32
 */
public class CPUTakeHighTest extends Thread{

    @Override
    public void run(){
        int i=0;
        while (true){
            i ++;
        }
    }
}
package com.chenfeilong.demo;

import com.chenfeilong.demo.JVM问题排查.CPUTakeHighTest;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) throws InterruptedException {
        SpringApplication.run(DemoApplication.class, args);
		
        new CPUTakeHighTest().start();
        Thread.sleep(10000000);
    }
}
  1. 使用top命令查看占用CPU过高的进程。如下图所示,途中看出线程id(PID)15868的java程序占用98.3的cpu。

image.png

  1. 通过jstack命令导出CPU占用高进程的线程栈。命令如下:
jstack 15868 >> java.txt

jstack是JVM自带的Java堆栈跟踪工具,它用于打印出给定的java进程ID、core file、远程调试服务的Java堆栈信息.

  1. 到指定目录下打开java.txt查看文件;
cat java.txt
  1. 搜素"runnable"关键字,如图,看出问题出于CPUTakeHighTest类的15行代,这样就直接定位到代码了。 image.png

导出的堆栈信息有线程的状态(一般要找RUNNABLE状态)和调用堆栈结合来查找问题。线程dump分析:线程dump分析主要目的是定位线程长时间停顿的原因.

原因线程状态举例
等待外部资源Runnable数据库连接、网络资源、设备资源
死循环Runnable代码Bug
Waiting活锁、死锁

文章参考于原文《Java中的CPU占用高和内存占用高的问题排查》