美文网首页
jvm程序执行慢分析

jvm程序执行慢分析

作者: 王康健_0124 | 来源:发表于2019-06-10 07:41 被阅读0次

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

    诊断步骤

    系统资源查看

    首先是系统资源查看,而且必须是在第一步。因为很多事故都是最开始慢后面就会出现卡死,被系统杀死,程序抛出异常结束等等情况,当时的状态没法保存下来,不行进行复盘,所以第一步先查看系统的资源,如果出现紧张情况,赶紧把状态保存。

    top命令

    查看基本就是top命令,可以看到系统cpu,内存等资源情况。经过查看系统资源大概可以分为以下情况。

    问题:cpu使用率过高。

    如果发现cpu成为了瓶颈的话,必须马上进行线程情况和当时cpu占用情况的保存。在糟糕的情况下,cpu可能被占满,那时候ssh都登录不上去了,就没法获取当时的情况。

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

    然后就会把线程cpu使用率特别高的线程栈打出来,然后可以分析这段逻辑了。

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

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

    这里必须打dump的原因是res过高,可能出发系统的oom killer,进程可能被系统杀死,此时不获取,可能进程就会被杀死了。如果不是系统资源问题,堆dump以后也是要用的。

    堆占用查看

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

    这里一般是开三个窗口对比看数据的。-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()。直接内存查看现在没有现成的工具。

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

    空间都不是特别紧张,但是gc次数频繁,并且不是system.gc()。那可能就是gc参数设置不对了,例如cms,老年代回收是一个2秒一次的轮训操作,很有可能是现在的空间占用每次都是满足gc的条件的,于是出现了这种情况。

    问题:gc时间特别长

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

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

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

    问题: 业务问题

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

    相关文章

      网友评论

          本文标题:jvm程序执行慢分析

          本文链接:https://www.haomeiwen.com/subject/ycqaxctx.html