当初大部分公司都有本人残缺的一套监控零碎,比方美团的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 参数示意输入锁信息

  1. 关上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