JVM调优实战场景一,CPU飙升100%

1、CPU异常高

异常代码如下:

@RestController
public class IndexController {

    private static boolean process=true;


    @RequestMapping("/user/cpu")
    public String cpu() throws InterruptedException {
        while(process){
            add(3,4);
        }
        return "sucess";
    }

    void add(int a,int b){
        int r = a + b;
    }
}

在linux启动项目后,服务器情况如下:top命令查看,基本没有什么占用cpu资源的进程

访问如下地址

http://101.132.143.77:8089/user/cpu

服务器cpu飙升

 1.1、排查

top命令看到占用cpu最高的进程pid为13861

top -p <pid>,显示你的java进程的内存情况,pid是你的java进程号

top -p 13861

显示如下:

 按H,获取每个线程的内存情况

 找到内存和cpu占用最高的线程tid,13885,转为十六进制得到363d,此为线程id的十六进制表示。

执行jstack pid | grep -A 10 tid 得到线程堆栈信息中363d这个线程所在行的后面10行,从堆栈中可以发现导致cpu飚高的调用方法

jstack 13861|grep -A 10 363d

结果如下:

 定位到代码位置:com.jvm.IndexController.cpu

 定位到问题代码,死循环,造成cpu飚高。

jstack是java虚拟机自带的一种堆栈跟踪工具,用于打印出给定的java进程id或core file或远程调式服务的java堆栈信息,主要分为两个功能:

a、针对活着的进程做本地的或远程的线程dump;

b、针对core文件做线程dump;

jstack用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做了什么事情,或者等待什么资源。

jstack命令主要用来查看java线程的调用堆栈,分析线程问题。