给一个系统定位问题时,理论知识、经验是关键基础,数据是依据,工具是运用知识处理数据的手段
所以在定位问题时,对于JVM相关的知识的理解非常关键,对这部分理论知识在这里就不详述了。
概述
工具分两大类,一类是命令行工具,一类是可视化工具
命令行工具是运行期定位线上问题的首选工具。
常用用法
用ps、jps找出线程号
如果怀疑是死循环、线程类的问题,使用jstack -l来查看
如果是jvm内存问题,使用jstate来进行查看,比较常用的是jstat -gcutil
如果线上问题通过命令行工具不能定位, 可以使用jmap导出快照,使用其他可视化工具进行分析,或者保留一台机器做现场。
注: jmap慎用,会stop the world,暂停JVM,慎用。
查看虚拟机进程状况,用于获取进程ID:jps
- 用于获取虚拟机进程的ID,该ID是其他命令行工具的输入
-
列出正在运行的虚拟机进程及进程的本地唯一ID(LVMID)对于本地虚拟机进程来说,LVMID和PID是一致的(用ps命令也可以拿到)
示例:
- jps -l
输出主类全名
- jps -v
输出启动参数
-
在本地使用ps命令也可以获取lvmidps -ef | grep java
查看虚拟机线程快照,用于定位死循序、死锁等:jstack
用于生成虚拟机当前时刻的线程快照,一般用于定位线程出现长时间停顿的原因,例如死锁、死循环等
-
jstack -l 3418我们一般查看用户进程,每个用户进程包括三部分内容:线程的状态线程的调用栈线程当前锁住的资源
一些小技巧:死循环: 可多次执行jstack,如果某个用户进程一直runnable,说明这个用户进程一直在运行,考虑是不是有死循环死锁: 存在互相等待,查看锁住的资源。 jstack可以直接检测线程状态:NEW: 至今尚未启动的线程的状态(jstack中不会出现)RUNNABLE: 可运行线程的线程状态。处于可运行状态的某一线程正在 Java 虚拟机中运行,但它可能正在等待操作系统中的其他资源,比如处理器。BLOCKED: 受阻塞并且正在等待监视器锁的某一线程的线程状态。(比如synchronized (lock) {}而lock被其他线程持有时,当前线程就会进入BLOCKED状态)WAITING 包括3种情况:不带超时值的 Object.wait不带超时值的 Thread.joinLockSupport.parkTIMED_WAITING 包括5种情况:Thread.sleep带有超时值的 Object.wait带有超时值的 Thread.joinLockSupport.parkNanosLockSupport.parkUntilTERMINATED 线程已终止(jstack中不会出现)
虚拟机统计信息监控,用于定位内存泄露、FullGC等: jstat
用于获取虚拟机各种运行状态信息,非常实用,
推荐在线定位GC问题的首选工具
用法: jstat option vmid interval count
对进程vmid运行jstat option,每隔interval时间,共运行count次
-
jstat -class查看类装载、卸载数量、总空间、以及类装载所耗费的时间
Loaded: 类装载数量 Bytes: 总空间(KB) UnLoaded:卸载数量 Time: 类装载耗费的时间(ms)
-
jstat -gc 3418 200 10查看堆状况,包括eden区、两个s区、老年代、持久代的容量、已用空间、GC时间等, 200ms执行一次,共执行10次S0C: 年轻代S0区的容量 S1C:年轻代S1区的容量 S0U:年轻代S0区目前已使用的空间 S1U:年轻代S1区已使用的容量 EC: 年轻代Eden的容量 EU:年轻代Eden已使用的容量OC:年老代的容量 OU: 年老代已使用的容量PC:Perm的容量 PU:Perm已使用的容量YGC: 从启动到现在YoungGC的次数 YGCT:YoungGC所用的时间(s)FGC:从启动到现在FullGC的次数 FGCT: 从启动到现在FullGC所用的时间(s)GCT: 从启动到现在GC的总时间GC会Stop the world,经常关注这个时间非常有意义,我们的报警里面也包含该信息。
-
jstat -gccapacity查看堆各个代使用的最大最小空间NGCMN: 年轻代最小的容量 NGCMX: 年轻代最大的容量 NGC:年轻代当前的容量 SOC S1C EC同上面的解释OGCMN:年老带最小的容量 OGCMX: 年老带最大容量, OGC: 年老代当前的容量 【OGC = sum(all OC),只有一个OC,OGC=OC】 OC: 年老代当前的容量PGCMN:Perm区的最小容量 PGCMX: Perm区最大容量 PGC:Perm区当前容量 PC: Perm区当前容量
-
jstat -gcutil查看堆各个代已使用空间占总空间的百分比,最常用的命令S0、S1、E、O、P 表示各个区已使用空间的百分比
-
监控各个代的情况jstat -gcnew 新生代的GC情况jstat -gcnewcapacity 新生代的最大、最小空间jstat -gcold 老年代的GC情况jstat -gcoldcapacity 老生代的最大、最小空间jsata -gcpermcapacity 永久带的最大、最小空间
上面这几个命令就不详解了,输出和上面类似。
Dump堆快照,保存现场、线下分析:Jmap
用于dump堆的快照,使用其他工具进行线下分析
例如: jmap -dump:format=b,file=a.bin 3418