初试Java VisualVM & ProcessorExplorer排查问题
背景
最近在学jvm,有个服务测试环境的接口查询超时,尝试使用jdk自带工具Java VisualVM定位一下问题。
测试环境权限限制无法导出dump文件,故在本地Windows环境排查。
Java VisualVM & ProcessorExplorer排查问题
整体思路是,启动服务调用接口后,使用jvisualvm工具观察cpu使用率和堆内存实时变化情况。ProcessorExplorer工具观察耗cpu的线程,拿到线程id后找到dump文件中的具体线程并进一步分析。
启动jvisualvm工具
- jdk的bin路径中启动jvisualvm.exe
- 观察服务的pid,查看[监视]标签实时观察cpu占用率、堆内存等变化情况
通过观察发现,cpu占用率高,前期gc频繁,因此可以找到cpu占用率高的线程,以便进一步发现原因。
ProcessorExplorer工具
-
windows自带的性能监视器有点难用,推荐使用ProcessorExplorer,下载地址 https://docs.microsoft.com/zh-cn/sysinternals/downloads/process-explorer
-
根据pid,找到对应的服务
-
双击服务,选择Threads标签可以观察线程的cpu占用情况
-
将这里的Tid(十进制)转换为十六进制,在dump中对应nid查找
这里以18036为例,十六进制为4674,然后通过dump排查。
Dump排查
在jvisualvm中右键服务选择线程dump,生成线程的dump文件,查找nid=4674的线程
可以发现该线程为GC线程,可以推断8核cpu下的ParallelGC的8个线程执行gc,导致cpu占用率高
jstat查看gc情况
采用jstat -gcutil 9804 2000 10命令观察gc情况
可以发现eden区以及old区占用率极高,gc频繁且时间长。
考虑代码问题导致大量对象生成,进而导致gc线程执行gc占用cpu。
jstack输出堆栈信息
采用jstack 9804 >>jstack.out命令,查看jstack.out文件
找到状态为runnable的线程,找到对应的方法排查导致大量对象生成的原因。
小结:本地排查使用调式即可,重在学习工具的使用和对jvm的理解,以便快速响应线上问题,共勉。