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线程的调用堆栈,分析线程问题。