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
分析
- 选择
dominator_tree
- 搜索被引用最多的
class
(在class name
下有一个正则的搜索框) - 然后右键选择
List Objects -> With incoming references
查看谁持有了它的引用
然后分析为什么这里会引用,最好看着代码分析。
以上是关于jstat和jmap打印堆栈排查内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章