jvm程序执行慢诊断手册

生产环境最多的几种事故之一就是程序执行慢,若是是web服务的话,表现就是响应时间长。本文分享,从业多年造成的排查守则。java

诊断步骤

系统资源查看

首先是系统资源查看,并且必须是在第一步。由于不少事故都是最开始慢后面就会出现卡死,被系统杀死,程序抛出异常结束等等状况,当时的状态无法保存下来,不行进行复盘,因此第一步先查看系统的资源,若是出现紧张状况,赶忙把状态保存。git

top命令

查看基本就是top命令,能够看到系统cpu,内存等资源状况。通过查看系统资源大概能够分为如下状况。github

问题:cpu使用率太高。

若是发现cpu成为了瓶颈的话,必须立刻进行线程状况和当时cpu占用状况的保存。在糟糕的状况下,cpu可能被占满,那时候ssh都登陆不上去了,就无法获取当时的状况。web

使用top -Hp pid获取线程cpu使用率高的tid
printf "%x\n" tid,获取线程id的16进制主要是为了在jstack中查看
jstack pid|grep tid(16)算法

而后就会把线程cpu使用率特别高的线程栈打出来,而后能够分析这段逻辑了。ssh

内存使用率太高或者没有系统资源占用太高

jmap -dump:format=b,file=heapdump.bin pidjvm

这里必须打dump的缘由是res太高,可能出发系统的oom killer,进程可能被系统杀死,此时不获取,可能进程就会被杀死了。若是不是系统资源问题,堆dump之后也是要用的。工具

堆占用查看

jstat -gc -h 10 pid 1000
jstat -gcutil -h 10 pid 1000
jstat -gccause -h 10 pid 1000spa

这里通常是开三个窗口对比看数据的。-gc主要是关注堆的分区总大小。-gcutil主要是关注已使用的百分比。-gccause主要是关注fgc次数,时间以及gc缘由。线程

内存问题的分类就比较多了,形成问题的卡顿的根本实际上是gc问题。stw的时候虚拟机停顿了,致使反应不过来了。

问题:堆内存占用空间接近满

这种状况就利用mat去查看dump分析吧,可能出现内存使用不合理或者内存泄漏,这里须要根据代码来分析。

问题:perm,metaspace占用接近满

jps -lvm

查看一下jvm参数设置,极可能是参数设置不合理,-XX:MetaspaceSize是发生gc的最小空间,这里是否是设置过小。MaxMetaspaceSize,MaxPermSize的值是否设置过小。java6若是设置都不小并且还占满了,那就得检测代码里是否是在运行时常量池加了字符串。1.7,1.8就考虑是否是业务用了什么字节码生成技术,动态作了一些字节码操做。

问题:system.gc()

gccause查看gc的缘由是system.gc()。须要检测是否用了rmi,使用了直接内存,或者业务代码调用了system.gc()。直接内存查看如今没有现成的工具。可使用我在github上放着的小工具查看。地址以下https://github.com/xpbob/jstatassist

问题:gc频繁但不是system.gc()

空间都不是特别紧张,可是gc次数频繁,而且不是system.gc()。那可能就是gc参数设置不对了,例如cms,老年代回收是一个2秒一次的轮训操做,颇有多是如今的空间占用每次都是知足gc的条件的,因而出现了这种状况。

问题:gc时间特别长

gc时间特别长,这个就从gc算法选择还有内存状况来协调参数吧。可是有两个特例,cms和g1。这两个垃圾回收器都是有单线程回收的算法的可能的,这里须要gc日志分析确认。

问题:堆占用不大,res特别大

这种状况可能性太大,常见的是jni,jna操做,mmap文件,直接内存使用,jdk的bug。须要根据实际状况来分析。

问题: 业务问题

若是以上表现都没有的话,那须要不断的打jstack去看线程栈的变化。这个只能是结合业务来看。

相关文章
相关标签/搜索