jstack 介绍
jstack 是 JDK 提供的一个命令行工具,用于生成 Java 进程的线程快照。
线程快照包含了 Java 进程中所有线程的状态信息,如线程的名称、线程的状态(RUNNABLE、WAITING、BLOCKED 等)以及线程的调用栈。
通过分析 jstack 生成的线程快照,可以帮助您诊断诸如死锁、线程阻塞、CPU 使用率过高等与线程相关的问题。
写了一个普通Java应用模拟CPU飙高,将它启动起来
输入top 命令进入top命令界面后,按大写字母 P
将根据CPU占用率排序, 按大写字母M
将根据内存占用率排序
top
查找CPU占用高的进程,复制进程PID 我这里是 461655
top -Hp {PID} 命令查看进程下的线程
top -Hp 461656
查找CPU占用高的线程,复制线程程PID 我这里是 461656
使用 printf “0x%x” {PID} 命令转换16进制
printf "0x%x" 461656
转为16进制后 0x70b58
jstack 是JDK提供的命令行工具,如果你配置了环境变量可以不用写全路径,没有环境变量就要加上你的JDK路径
# jstack 进程PID # |grep 0x70b58 过滤出该线程相关调用栈信息 # -A 50 输出后50行 /usr/local/jdk1.8.0_301/bin/jstack 461655 |grep 0x70b58 -A 50
以下输出调用栈中,可以看到在App.java中main方法第10行调用了线程就一直处于 java.lang.Thread.State: RUNNABLE
执行状态
根据调用栈信息查看源码,原来代码中在计算圆周率后800万位。非常消耗CPU资源。
App.java
文件内容
package org.github.zuuyao; import java.math.BigDecimal; import java.math.RoundingMode; public class App { public static void main(String[] args) { System.out.println("calculatePi!"); // 计算圆周率精确到小数点八百万位 BigDecimal bigDecimal = calculatePi(8000000); System.out.println("pi Value : " + bigDecimal.toString()); } /** * 模拟CPU飙高 */ public static void simulation() { while (true) { // 什么都不执行,一直死循环。占用大量CPU资源 } } /** * 计算圆周率 * * @param decimalPlaces 圆周率小数点位数 * @return 计算结果 */ public static BigDecimal calculatePi(int decimalPlaces) { BigDecimal pi = BigDecimal.ZERO; BigDecimal sixteen = BigDecimal.valueOf(16); BigDecimal one = BigDecimal.ONE; for (int k = 0; k <= decimalPlaces; k++) { BigDecimal kBig = BigDecimal.valueOf(k); BigDecimal term = one.divide(sixteen.pow(k), decimalPlaces + 10, RoundingMode.HALF_UP); term = term.multiply( BigDecimal.valueOf(4) .divide(BigDecimal.valueOf(8 * k + 1), decimalPlaces + 10, RoundingMode.HALF_UP) .subtract(BigDecimal.valueOf(2) .divide(BigDecimal.valueOf(8 * k + 4), decimalPlaces + 10, RoundingMode.HALF_UP)) .subtract(BigDecimal.valueOf(1) .divide(BigDecimal.valueOf(8 * k + 5), decimalPlaces + 10, RoundingMode.HALF_UP)) .subtract(BigDecimal.valueOf(1) .divide(BigDecimal.valueOf(8 * k + 6), decimalPlaces + 10, RoundingMode.HALF_UP)) ); pi = pi.add(term); } return pi.setScale(decimalPlaces, RoundingMode.HALF_UP); } }
pom.xml
文件内容
4.0.0 org.github.zuuyao troubleshooting-demo 1.0-SNAPSHOT jar troubleshooting-demo http://maven.apache.org UTF-8 ${artifactId} org.apache.maven.plugins maven-jar-plugin true org.github.zuuyao.App