使用jdk常用工具排查故障流程

如题所述

第1个回答  2022-07-09

jps定位进程
jstat统计堆信息
jstack定位问题线程
jmap定位问题对象

jps用于查看服务器当前有哪些java进程,排查问题时,一般先使用jps定位到pid
-l参数可以打印完整类路径或jar包路径,-v参数可以打印启动参数
备注: ps -ef | grep java 可以打印启动参数和jar路径,但打印不了类路径


jstat用于统计堆各区域的使用情况等信息

下图中, jstat -gc 1 1000 5 命令表示每1000ms打印一次pid为1的进程的堆的信息,共打印5次。
S0C表示S0的capacity,即总容量,S0U表示S0的used,即已使用空间,单位为kb,U/C可以得到使用率,如MU/MC = 元空间使用率。
E、O、M分别表示Eden区、老年代、元空间,YGC/YGCT表示YGC的GC次数/GC时间,FGC/FGCT表示FGC的GC次数/GC时间。

-gc参数显示具体数值,-gcutil展示比例


jstack用于查看某个进程内的线程信息,常用于排查cpu问题

使用jstack时,一般步骤如下
步骤1,用 top -Hp pid 查看pid进程内的线程的cpu占比,按cpu使用率从大到小排序。
本步骤需要着重观察的是: cpu占比较高的线程,以及cpu运行时间(即TIME+列)较长的线程

这里有一个问题,cpu多高算高?
假设有一个4核的cpu,一个核跑满是100%,整个cpu最高跑到400%。
如果有一个线程死循环(while true),cpu一般能到90%+,到不了100%是因为即使是while true,还是会有时间片轮转。

另外,cpu运行时间也是一个很重要的指标,上图中,pid为71的线程,跑了2小时18分钟,肯定有问题。

步骤2,把当前线程信息导出thread dump文件

步骤3,根据上一步找到的问题线程的pid,把pid转成16进制,因为thread dump文件中,线程pid是用16进制表示的

步骤4,在thread dump文件中检索上一步算出的线程pid的16进制,一般看后20行,能看到完整调用栈即可

可以看到,该线程是kafka消费者线程

注意: 开发时,线程名一定要定好,能对应具体业务,这样用jstack的时候,可以根据线程名马上定位到具体业务。

另外,Thread类的getAllStackTraces方法可以获取当前虚拟机所有线程的调用栈,如果开发人员不方便上生产,可以用该api暴露接口。


jmap用于查看某个进程的对象信息,常用于排查内存问题

jmap -dump:live,format=b,file=/root/1.hprof 1 把堆的内容打印到文件,live参数表示只输出活的对象。
备注:
heap dump文件的大小与当前堆使用量的大小一致,假如堆使用量为2G,heap dump文件就有2G,导出heap dump文件需要很长的时间,导出过程可能会影响对外服务。
另外,heap dump文件只有用专业的工具(如jhat、jvisualvm、mat)才能看,无法用grep等命令检索。
综上,一般很少在生产环境使用该命令。

jmap -histo:live pid 统计类实例数以及字节数。
一般用 jmap -histo:live pid | grep packge 检查是否内存泄漏,page为java项目的包名

jmap -J-D64 -heap 1 打印heap的概要信息


按上面的步骤,一般可以定位到问题,但是比较困难,需要在短时间内做大量操作,因此,推荐使用 阿里的arthas 。

相似回答