jstat和jmap打印堆栈排查内存泄漏

Posted 好大的月亮

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jstat和jmap打印堆栈排查内存泄漏相关的知识,希望对你有一定的参考价值。

思路

先是前端反应请求timeout,这个时候先看对应微服务,发现请求没有进来,此时tomcat日志里还没打印出oom。然后去看网关,发现请求timeout。此时再回过头去看对应微服务的tomcat日志。发现内存泄漏。

此时先查看gc情况,然后查看对象的引用情况,内存泄漏了肯定是有一个对象有大量的实例没有被gc回收,最后打印堆栈。

查看gc

5秒一次查看,主要看老年代的剩余空间fgc的次数

jstat -gcutil pid 5000

下面是一个命令demo,并不是出现问题那个时候的gc情况

查看对象引用情况

要在fgc前后分别打印,查看存活的对象中哪些引用比较高,高的离谱的一般就是它了.

我在排查到这一步的时候就发现了logback中的一个对象引用特别高,然后一看项目的logback里除了正常日志,还有logstash相关配置,猜测logstash相关对象没有被回收,然后注释后重启问题解决.

#打印全部
jmap -histo:live pid > pid.histo
#打印前十个引用最多的
#jmap -histo:live 8703 | sort -n -r -k 2 | head -10

less pid.histo

命令demo,并不是出现问题那个时候的对象引用情况

打印堆栈

这里要注意线上导出的时候会stop world,所以最好在开发环境中复现之后再开发环境中导出

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

然后用mat分析

  1. 选择dominator_tree
  2. 搜索被引用最多的class(在class name下有一个正则的搜索框)
  3. 然后右键选择List Objects -> With incoming references查看谁持有了它的引用

然后分析为什么这里会引用,最好看着代码分析。

以上是关于jstat和jmap打印堆栈排查内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章

内存溢出排查基本步骤

jvm内存堆栈监控之jmap篇

JVM调优工具的使用(jps,jstat,jstack,jmap,jhat)

使用jdk常用工具排查故障流程

solr调优化和问题排查

一个java内存泄漏的排查案例