Java 演示生产环境 cpu 飙高及排查思路
环境信息
生产环境模拟服务器:阿里云 Centos7
服务器安装 jdk 版本:1.8.0
cpu 飙高代码 CpuHighDemo
模拟 cpu 飙高,死循环即可:
import java.util.UUID;
public class CpuHighDemo {
public static void main(String[] args) {
while (true) {
System.out.printf("%s: %s\n", Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0, 8));
}
}
}
将上述代码放到阿里云 Centos7 服务器上,编译:
javac CpuHighDemo.java
示意图如下:
为了方便当前端口执行排查操作,故后台运行 CpuHighDemo
:
nohup java CpuHighDemo &
示意图如下:
我们看一下 nohup.out
里的输出内容:
说明程序在不停打印
排查思路及步骤
1. top 命令找出 cpu 占比最高的进程
top
可看出当前 cpu 占比最高的是 PID = 14073
的 java 进程
2. ps -ef 或者 jps 进一步定位进程信息
ps -ef | grep -v grep | grep PID
3. 定位到进程内具体线程
# PID 为上一步定位到的进程编号
ps -mp PID -o THREAD,tid,time
得到 PID = 14073
进程内 cpu 占比最高的线程为 tid = 14074
的线程
4. 将定位到的线程 tid 转换为 16 进制
# 将十进制的 tid 转换为 16 进制输出(默认是大写英文模式)
# 该方法可将任意十进制数 tid 转换为任意 obase 的 value 进制的数值
echo "obase=16;tid" | bc
# 将十进制的 tid 转换为 16 进制英文小写格式输出(方法 1)
echo "obase=16;tid" | bc | awk '{print tolower($0)}'
# 将十进制的 tid 转换为 16 进制英文小写格式输出(方法 2)<推荐方法>
printf "%x\n" tid
5. 查看定位到的线程堆栈信息
# 查看定位到的线程堆栈信息,注意 tid 需要十六进制形式
jstack PID | grep -i tid(十六进制形式) -A60
已定位出报错的具体代码位置