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


    思路

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

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

    查看gc

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

    jstat -gcutil pid 5000
    
    • 1

    下面是一个命令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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    命令demo,并不是出现问题那个时候的对象引用情况
    在这里插入图片描述

    打印堆栈

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

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

    然后用mat分析

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

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

  • 相关阅读:
    STM32人脸识别系统设计(程序代码+论文)
    js正则匹配获取分组和正向反向的区别
    【无标题】
    华纳云:redis缓存失效策略怎么配置
    吾爱破解置顶的“太极”,太好用了吧!
    【MM小贴士】副产品 工单核算
    柯桥实用口语学习,韩语口头禅系列短句-恋爱篇
    Symfony 简介
    STM32智能仓储管理系统教程
    C++11标准模板(STL)- 算法(std::unique_copy)
  • 原文地址:https://blog.csdn.net/weixin_43944305/article/details/126120313