美文网首页
记一次内存泄漏排查

记一次内存泄漏排查

作者: OPice | 来源:发表于2019-11-16 14:04 被阅读0次

    1、现象

    httpclient一直read time out,使用jmx 产看内存是每天都在上升的。

    2、保存现场

    jstack pid > jstack.log 保存栈日志
    jmap -dump:format=b,file=heap.log pid 保存堆日志
    一般情况会设置(-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heapdump.hprof) 遇到内存溢出会自动生成dump文件

    3、止血(如果不需要可先排查问题)

    重启应用,恢复服务,先止血。或者不影响服务的话可以直接连上服务器分析,不用分析日志。

    4、分析排查

    两种方案:

    • 分析日志
      grep 'java.lang.Thread.State' jstack.log | wc -l 查看栈的数量
      grep -A 1 'java.lang.Thread.State' jstack.log | grep -v 'java.lang.Thread.State' | sort | uniq -c |sort -n
    • 查看栈的状态
      使用 MAT 分析 jvm heap ,下载堆 dump 文件
      堆文件都是一些二进制数据,在命令行查看非常麻烦,Java 为我们提供的工具都是可视化的,Linux 服务器上又没法查看,那么首先要把文件下载到本地。
      由于我们设置的堆内存为 4G,所以 dump 出来的堆文件也很大,下载它确实非常费事,不过我们可以先对它进行一次压缩。
      gzip 是个功能很强大的压缩命令,特别是我们可以设置 -1 ~ -9 来指定它的压缩级别,数据越大压缩比率越大,耗时也就越长,推荐使用 -6~7, -9 实在是太慢了,且收益不大,有这个压缩的时间,多出来的文件也下载好了
    • 服务器上即时排查
      1、top 查看服务器内存硬盘状况
      2、jinfo pid 查看java 内存情况
      3、jstat -gcutil [pid] 60000 查看从程序启动到现在进行了多少FGC,查看下old区百分比
      jmap -histo:live [pid] >f 打印堆内存存活对象信息
      vi f

    5、定位问题

    根据第四步分析出具体oom对象,发现一个connectManager被放到了map中,map的clear是跟httpclient shutDown一块的。但是项目原因,封装的阿里云 apachHttpclient,每次的ak和sk不一样所以每次创建一个新的client,所以map一直在增加没有被释放。

    相关文章

      网友评论

          本文标题:记一次内存泄漏排查

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