Windows 环境下如何进行线程 Dump 分析
现在大部分公司都有自己完整的一套监控系统,比如美团的 CAT,我们公司的监控系统也是基于 CAT 做的二次开发。一般测试环境或生产环境有问题可以直接使用这些系统查看线程和内存运行情况,分析排查问题。
但对于我们开发人员来说还是有必要了解最原始的排查流程,也就是不借助这些系统,使用最基本的命令解决,毕竟了解了这些底层实现对自身发展也是有帮助的。
网上搜下这样的文章其实很多,比如排查 cpu 过高,死锁问题的文章,但大部分讲的都是 Linux 环境下怎么做,其实很多问题在本地开发时就能发现和排查,所以我主要讲下 Windows 环境下如何排查,这里举例讲下 java 应用出现死锁问题的排查方法。
主要有两种方式,一种是使用 JVM 指令+Process Explorer 工具,另一种是使用 jdk/bin 目录下的 jvisualvm.exe 工具
一. JVM 指令+Process Explorer
常用 JVM 指令:
jps
主要用来输出 jvm 运行的进程状态jstack
查看某个 java 进程内的线程堆栈信息
全部命令可参考官方文档说明
Process Explorer 是 windows 系统的进程管理器,可以查看对应 pid(进程 id)下的线程信息,方便定位到哪个线程占有的 cpu 资源高。
排查过程:
1. 打开 Process Explorer 工具,找到自己的 java 应用,如果不清楚出问题的 java 进程是哪个,可以在 windows 的 cmd 命令窗口里输入 jps 指令查看所有 java 应用的进程 id,如图:
如果还不能确定哪个 pid 是你的 java 应用,可以加上 -lm 参数,
即:jps -lm
,打印出详细的类名,方便找到对应的 pid
还有一种方式是在任务管理器(任务管理器-查看-选择列-pid)里也能找到对应的 pid
2. 根据第一步找到的 pid 在 Process Explorer 工具找到那一行记录然后双击打开 Thread 一栏的 tab,就能看的 java 进程 pid 对应的线程信息,TID 就是对应的线程 id,如图:
3. 在 cmd 命令行窗口使用jstack
指令把 java 应用的栈信息 dump 到本地分析,当然也可以直接在命令行窗口分析,但是一般堆栈信息都比较大,所有的线程信息都在里面,我们只关心出问题线程的堆栈信息,这样的话的可以使用: jstack pid|findstr tid
这个指令查找我们关心的线程 id,但还是建议 dump 到本地查找,这里的 tid 要注意一下,jstack
里的线程 id 是用十六进制表示的,需要把第 2 步里的 tid(十进制)转为十六进制,如图:
jstack 指令后面的 -l 参数表示输出锁信息
打开 dump 文本文件,通过十六进制的 tid 找到对应的堆栈信息,就可以定位到具体的业务代码调用位置:
从上图可以看出出问题的代码是在 DeadLockTest 的 70 行,线程的状态是 BLOCKED,因为 dump 线程时加上了 -l 的参数(jstack -l pid),所以在 dump 的最下方 jvm 会输出死锁的信息:
很明显 Thread-1 线程在等待 0x000000076b940cf0 这个锁,它本身持有 0x000000076b940d00 这个锁,而 Thread-0 刚好在等待 0x000000076b940d00 这个锁,它本身持有的锁是 0x000000076b940cf0,这样成了两个线程互相等待对方手里持有的锁,导致了死锁的出现。
二. jvisualvm.exe 工具
这个工具在 JDK 的安装目录的 bin 文件夹里,打开后也是找到对应的 pid,它其实是访问我们 JVM 虚拟机里的堆栈信息,优点就是直观和方便查看线程运行情况,如果有死锁也会提示出来,如图:
文章来源:http://javakk.com/176.html
评论