详解 jstack 命令的用法

JAVA herman 2030浏览
公告:“业余草”微信公众号提供免费CSDN下载服务(只下Java资源),关注业余草微信公众号,添加作者微信:xttblog,发送下载链接帮助你免费下载!
本博客日IP超过1800,PV 2600 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog,之前的微信号好友位已满,备注:返现
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
视频教程免费领

大家最近可能会发现我写的文章都很套路,一个系列一个系列的。前面写了一系列的数据结构,最近我会开始给大家介绍一些 Java 中的一些自带命令、工具的使用。如果你长期的关注和阅读,我相信不到一年你就是一个高手。至少你和高手在一起同行,面试绝对不会有问题。

今天我们继续来学习一个 java 自带的命令 jstack。

jstack 命令非常的简单,我们可以通过 jstack -h 或者 jstack -help 命令查看它的用法详情。

jstack -help
Usage:
    jstack [-l] <pid>
        (to connect to running process)
    jstack -F [-m] [-l] <pid>
        (to connect to a hung process)
    jstack [-m] [-l] <executable> <core>
        (to connect to a core file)
    jstack [-m] [-l] [server_id@]<remote server IP or hostname>
        (to connect to a remote debug server)

Options:
    -F  to force a thread dump. Use when jstack <pid> does not respond (process is hung)
    -m  to print both java and native frames (mixed mode)
    -l  long listing. Prints additional information about locks
    -h or -help to print this help message

从上面可以看出 jstack 命令主要有 4 个参数:

  • -F 当进程挂起,执行jstack <pid> 命令没有任何输出后,将强制转储堆内的线程信息
  • -m 在混合模式下,打印 java 和 native c/c++ 框架的所有栈信息
  • -l 长列表。打印关于锁的附加信息,例如属于 java.util.concurrent 的 ownable synchronizers 列表
  • -h | -help 打印帮助信息

说一下,有些人可能还不知道 pid 是什么?pid 就是 Java 的进程 id,可以使用我们上一篇中的 jps 查看(Java 高大上的虚拟机进程状态管理工具 jps 使用教程!)。

当我们要查看堆栈信息可以执行 jstack 88888(pid)。88888 是我的一个 java 进程 id,每个进程的 id 都不一样。

直接在控制台查看,太麻烦了。我们可以使用下面的命令,将 jstack 结果输出到文件中。

jstack -l 88888 >1.txt

输出的内容大致如下,只列一小部分:

Full thread dump Java HotSpot(TM) Client VM (20.45-b01 mixed mode, sharing):

"Attach Listener" daemon prio=10 tid=0x08251400 nid=0x11bd runnable [0x00000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"DestroyJavaVM" prio=10 tid=0xb3a0a800 nid=0xffa waiting on condition [0x00000000]
   java.lang.Thread.State: RUNNABLE

如果不知道怎么分析,可以查看我的这篇文章《jvm hs_err_pid.log 文件分析工具 CrashAnalysis 使用教程》。

或者使用我下面的这个脚本。

#!/bin/sh
JAVA_HOME=/home/q/java/default
WEB_HOME=/home/q/www
jstack="$JAVA_HOME/bin/jstack"
processId=$1
#如果没有输入进程ID,提示用户输入
if [ ! -n "$processId" ] ;then
    echo "please input a java processId "
    read processId
fi
echo $processId
#如果是标准输出则变成红色,否则正常输出
redEcho(){
   if [ -c /dev/stdout ] ; then
       echo -e "\033[1;31m$@\033[0m"
   else
       echo "$@"
   fi
}
showProcessAllthreads(){
   while read eachLine ; do
      threadId=`echo $eachLine | awk '{print $1}'`
      threadId0x=`printf %x ${threadId}`
      pcpu=`echo ${eachLine} | awk '{print $2}'`
      totalTime=`echo ${eachLine} | awk '{print $3}'`
      #存储文件
      jstackFile=/tmp/${uniqueId}_${processId}
      sudo -u tomcat $jstack ${processId} > ${jstackFile} || {
          redEcho "failed to use jstack commond on java process ${processId}"
          rm -rf ${jstackFile}
          continue
      }
      redEcho "java processId is [${processId}] : current thread is(${threadId}/${threadId0x}) : cost total process time is [${totalTime}] : use total cup precent is [${pcpu}]"
      sed "/nid=0x${threadId0x}/,/^$/p" -n ${jstackFile}
   done
}
#为当前的程序的文件生成一个唯一的地址(时间+随机数+进程号(注意这个进程号是当前程序的进程号,不是java城市的进程号))
uniqueId=`date +%s`_${RANDOM}_$$
echo $uniqueId
top -p $processId -H -n 1 -b | sed -n "8,1000p" | awk '{print $1,$9,$11}' | showProcessAllthreads
rm -rf /tmp/${uniqueId}

对线程状态不了解的,可以看我的这篇文章《了解多线程,先从“图”了解线程的基本状态》。

业余草公众号

最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加作者微信号1:xmtxtt(5000人已满),微信号2:codedq(5000人已满),微信号3:xttblog(超2800)。备注:“xttblog”,添加博主微信拉你进微信群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作也可添加作者微信进行联系!

本文原文出处:业余草: » 详解 jstack 命令的用法