大家最近可能会发现我写的文章都很套路,一个系列一个系列的。前面写了一系列的数据结构,最近我会开始给大家介绍一些 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}
对线程状态不了解的,可以看我的这篇文章《了解多线程,先从“图”了解线程的基本状态》。
: » 详解 jstack 命令的用法
原创文章,作者:6024010,如若转载,请注明出处:https://blog.ytso.com/251987.html