JStack 线程转储分析器

JStack 线程转储分析器

原文: https://howtodoinjava.com/linux/how-to-get-thread-dump-in-linux-using-jstack/

线程转储是 Java 虚拟机(JVM)中当前活动的所有 Java 线程的列表。 有几种方法可以从 JVM 提取线程转储。 强烈建议在分析任何问题(例如死锁或资源使用情况分析)时采取多个线程转储。 最好在多个线程转储中进行确认,然后单次尝试得出结论。

1.获取 Java 进程的 PID

获得线程转储所需的第一条信息是 Java 进程的 PID。

Java JDK 附带jps命令,该命令列出了所有 Java 进程 ID。 您可以这样运行此命令:

$ jps -l

记住 – 您可能必须以$ sudo -u jps -l运行此命令,其中“user”是正在运行的 Java 进程用户的用户名。

即使现在,如果您仍无法找到进程 ID,请使用以下命令:

$ ps -aef | grep java

2.从 JVM 请求线程转储

如果已安装/可用,我们建议使用 jstack 工具。 它将线程转储打印到命令行控制台。

要使用 jstack 获得线程转储,请运行以下命令:

$ jstack

您可以使用控制台输出redirect/append伪指令将连续的线程转储输出到文件中:

$ jstack  >> threaddumps.log

要点

  1. 从 JDK 1.5 开始,可以使用 jstack 工具。
  2. 即使启用了-Xrs jvm参数,jstack 也可以工作。
  3. 无法使用 JDK 1.6 中的 jstack 工具从运行在 JDK 1.5 上的进程中进行线程转储。

3.使用 jstack 脚本以固定的时间间隔进行线程转储采样

这个简单的 Shell 脚本以固定的时间间隔拍摄了几个 jstack 快照(参考文档):

#!/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

像这样使用上面的脚本:

$ jstackSeries  10 5

4.如何比较两个 JStack 线程转储

比较线程转储,您可以使用交互式差异查看器,例如:

$ vimdiff file1 file2 file3 file4 # up to 4 files

查看 jstack 跟踪的哪些部分随时间变化的另一种方法是使用$ context diff(-c 选项)比较相邻的 jstack 跟踪:

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 线程转储在文件之间更改的位置。

学习愉快!