生产环境最多的几种事故之一就是程序执行慢,若是是web服务的话,表现就是响应时间长。本文分享,从业多年造成的排查守则。java
首先是系统资源查看,并且必须是在第一步。由于不少事故都是最开始慢后面就会出现卡死,被系统杀死,程序抛出异常结束等等状况,当时的状态无法保存下来,不行进行复盘,因此第一步先查看系统的资源,若是出现紧张状况,赶忙把状态保存。git
查看基本就是top命令,能够看到系统cpu,内存等资源状况。通过查看系统资源大概能够分为如下状况。github
若是发现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分析吧,可能出现内存使用不合理或者内存泄漏,这里须要根据代码来分析。
jps -lvm
查看一下jvm参数设置,极可能是参数设置不合理,-XX:MetaspaceSize是发生gc的最小空间,这里是否是设置过小。MaxMetaspaceSize,MaxPermSize的值是否设置过小。java6若是设置都不小并且还占满了,那就得检测代码里是否是在运行时常量池加了字符串。1.7,1.8就考虑是否是业务用了什么字节码生成技术,动态作了一些字节码操做。
gccause查看gc的缘由是system.gc()。须要检测是否用了rmi,使用了直接内存,或者业务代码调用了system.gc()。直接内存查看如今没有现成的工具。可使用我在github上放着的小工具查看。地址以下https://github.com/xpbob/jstatassist
空间都不是特别紧张,可是gc次数频繁,而且不是system.gc()。那可能就是gc参数设置不对了,例如cms,老年代回收是一个2秒一次的轮训操做,颇有多是如今的空间占用每次都是知足gc的条件的,因而出现了这种状况。
gc时间特别长,这个就从gc算法选择还有内存状况来协调参数吧。可是有两个特例,cms和g1。这两个垃圾回收器都是有单线程回收的算法的可能的,这里须要gc日志分析确认。
这种状况可能性太大,常见的是jni,jna操做,mmap文件,直接内存使用,jdk的bug。须要根据实际状况来分析。
若是以上表现都没有的话,那须要不断的打jstack去看线程栈的变化。这个只能是结合业务来看。