企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
# JStack 线程转储分析器 > 原文: [https://howtodoinjava.com/linux/how-to-get-thread-dump-in-linux-using-jstack/](https://howtodoinjava.com/linux/how-to-get-thread-dump-in-linux-using-jstack/) 线程转储是 Java 虚拟机(JVM)中当前活动的所有 Java 线程的列表。 有几种方法可以从 JVM 提取[线程](https://howtodoinjava.com/java/multi-threading/java-thread-life-cycle-and-thread-states/)转储。 强烈建议在分析任何问题(例如[死锁](https://howtodoinjava.com/java/multi-threading/writing-a-deadlock-and-resolving-in-java/)或资源使用情况分析)时采取多个线程转储。 最好在多个线程转储中进行确认,然后单次尝试得出结论。 ## 1.获取 Java 进程的 PID 获得线程转储所需的第一条信息是 Java 进程的 PID。 Java JDK 附带`jps`命令,该命令列出了所有 Java 进程 ID。 您可以这样运行此命令: ```java $ jps -l ``` ***记住*** – 您可能必须以`$ sudo -u jps -l`运行此命令,其中“`user`”是正在运行的 Java 进程用户的用户名。 即使现在,如果您仍无法找到进程 ID,请使用以下命令: ```java $ ps -aef | grep java ``` ## 2.从 JVM 请求线程转储 如果已安装/可用,我们建议使用 [**jstack**](https://docs.oracle.com/javase/1.5.0/docs/tooldocs/share/jstack.html "jstack") 工具。 它将线程转储打印到命令行控制台。 要使用 jstack 获得**线程转储**,请运行以下命令: ```java $ jstack ``` 您可以使用控制台输出`redirect/append`伪指令将连续的线程转储输出到文件中: ```java $ jstack >> threaddumps.log ``` **要点** 1. 从 JDK 1.5 开始,可以使用 jstack 工具。 2. 即使启用了`-Xrs jvm`参数,jstack 也可以工作。 3. 无法使用 JDK 1.6 中的 jstack 工具从运行在 JDK 1.5 上的进程中进行线程转储。 ## 3.使用 jstack 脚本以固定的时间间隔进行线程转储采样 这个简单的 Shell 脚本以固定的时间间隔拍摄了几个 jstack 快照([参考文档](https://wiki.eclipse.org/How_to_report_a_deadlock#jstackSeries_--_jstack_sampling_in_fixed_time_intervals_.28tested_on_Linux.29 "jstack refernce")): ```java #!/bin/bash if [ $# -eq 0 ]; then echo >= 2 "Usage: jstackSeries [ count [ delay ] ]" echo >= 2 " Defaults: count = 10, delay = 1 (seconds)" exit 1 fi pid=$1          # required count=${2:-10}  # defaults to 10 times delay=${3:-1} # defaults to 1 second while [ $count -gt 0 ] do     jstack $pid >jstack.$pid.$(date +%H%M%S.%N)     sleep $delay     let count--     echo -n "." done ``` 像这样使用上面的脚本: ```java $ jstackSeries 10 5 ``` ## 4.如何比较两个 JStack 线程转储 要**比较线程转储**,您可以使用交互式差异查看器,例如: ```java $ vimdiff file1 file2 file3 file4 # up to 4 files ``` 查看 jstack 跟踪的哪些部分随时间变化的另一种方法是使用`$ context diff`(-c 选项)比较相邻的 jstack 跟踪: ```java d_old="" for d in jstack.13585.12171* do   if [ -n "$d_old" ]   then     diff -c "$d_old" "$d"   fi   d_old="$d" done ``` 在这里,结果仅显示 **JStack 线程转储**在文件之间更改的位置。 学习愉快!