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#最多4个文件

查看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线程转储在文件之间变化的位置。

saigon has written 1445 articles

Leave a Reply