• Java应用生产Full GC或者OOM问题如何定位


    1 引言

    生产应用服务频繁Full GC却无法释放内存,甚至可能OOM,这种情况很有可能是内存泄露或者堆内存分配不足,此时需要dump堆信息来定位问题,查看是哪些地方内存泄漏。

    Dump文件也称为内存转储文件或内存快照文件,是一个进程或者系统在某一个给定时间的内存快照。例如当进程崩溃或进程出现其它问题时,甚至在任何时候,我们都可以使用工具备份系统或进程的内存进行调试和分析。它包含模块信息、线程信息、堆栈调用信息、异常信息等。

    2 查看java服务进程pid

    ps -aux|grep java

    3 GC简单分析

    可使用jdk自带的jstat简单分析一下gc情况

    # 每隔 1000毫秒输出一次 jstat -gcutil 1000

    输出如下:

    ----------------------------------------

    S0 S1 E O M CCS YGC YGCT FGC FGCT GCT

    0.00 66.15 28.84 77.76 93.88 91.90 183 1.058 4 0.517 1.575

    0.00 66.15 29.51 77.76 93.88 91.90 183 1.058 4 0.517 1.575

    0.00 66.15 30.45 77.76 93.88 91.90 183 1.058 4 0.517 1.575

    -----------------------------------------

    S0:幸存区survivor0使用百分比

    S1:幸存区survivor1使用百分比

    E:新生代Eden使用百分比

    O:老年代Old使用百分比

    M:元数据 Metaspace使用百分比

    CCS:压缩类空间Compressed class space使用百分比

    YGC:Young GC次数

    YGCT:Young GC耗时,毫秒

    FGC:Full GC次数

    FGCT:Full GC耗时,毫秒

    GCT:GC总耗时

    2次相邻的GC,可以快速判断那一次GC的耗时;GCT / GC = 平均每次GC耗时

    GC是否频繁标准参考:Young GC执行迅速(50毫秒以内)、Young GC执行不频繁(间隔10秒左右一次)、Full GC执行迅速(1秒以内)、Full GC执行不频繁(间隔10分钟左右一次)

    如发现Full GC次数频繁增加,Young GC次数不变或变化很小,这就是堆内存不足,很有可能就是内存泄漏的问题。

    4 导出dump文件

    分析dump文件首先要获取dump文件,获取方法基本有2种

    4.1 设置JVM的环境变量

    -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/logs/xxx.hprof

    那在OOM的时候会自动在指定目录生产dump文件,此时只需要在指定目录获取即可

    4.2 通过jmap获取

    jmap -dump:live,format=b,file=/logs/xxx.hprof 

    5 分析dump文件

    对于小于自身电脑内存的dump文件,可尝试下载到本地进行分析,可使用的工具有:JVisualVM、JHat、MAT

    5.1 使用JVisualVM

    在jdk的bin目录下面有JVisualVM,打开它,然后选中文件->装入,选则dump文件,即可

    点击异常错误的线程:XNIO-1 task-1,等待一会既可以打开堆转储上的线程的指定OOM的地方

    查看具体实例数量和占用大小

    点击类 -> 在实例数最多的类名上右击 -> 选择在实例视图中展示 -> 查看引用

    右键选择在线程中显示,可以查询详情

    5.2 使用jhat

    jhat -J-Xmx1024M [file]

    执行后等待console中输出Started HTTP on port 7000,看到后就可以通过浏览器访问http://ip:7000了,此页面默认为按package分类显示系统中所有的对象实例。在页面的最下端有Other Queries导航,其中有显示jvm中对象实例个数的链接、有显示jvm中对象大小的链接等,点击显示jvm中对象大小的链接,jhat在分析大的堆dump文件时表现不好,速度很慢。

    5.3 使用mat(推荐)

    5.3.1 下载

    mat下载地址:https://eclipse.dev/mat/previousReleases.php

    根据jdk版本下载合适的mat版本,可以通过uname -a命令查看服务器的操作系统版本号

    1. [root@xxx ~]# uname -a
    2. Linux xxxx 3.10.0-1127.19.1.el7.x86_64 #1 SMP Tue Aug 25 17:23:54 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

       使用的是JDK1.8,系统是x86_64,需要选择如下版本:

    5.3.2 解压

    unzip MemoryAnalyzer-1.8.0.20180604-linux.gtk.x86_64.zip

    5.3.3 修改内存

    vi MemoryAnalyzer.ini

    5.3.4 文件分析

    ./ParseHeapDump.sh [hprof文件] org.eclipse.mat.api:suspects org.eclipse.mat.api:overview org.eclipse.mat.api:top_components

    其中hprof文件在实际使用的时候需要替换为hprof文件的路径。运行完毕后在hprof文件所在目录会生成一系列的index/threads文件和3个压缩文件。这3个压缩文件是我们重点关注的分析报告,分别为:

    • xxx_Leak_Suspects.zip:报告包含怀疑造成内存泄漏的地方,报告中包含了class层级图。对于OOM的场景能够很容易的定位到是哪个对象占用了大量内存不释放。
    • xxx_System_Overview.zip:包含heap dump基本信息,dump进程JVM的相关配置和线程信息等。
    • xxx_Top_Components.zip:查看占用空间最大的几个object/class/classloader/package等。报告以饼图和表格的形式展示。通过这个报告可以定位出Java程序运行时哪些对象占用内存较多,对问题排查和程序优化很有帮助。

    这三个报告是分析问题的关键。我们通过报告找出内存占用过大的对象,然后结合日志和项目源代码分析程序逻辑,逐步定位出问题。

    主要看xxx_Leak_Suspects.zip,解压,打开index.html

         大部分情况很容易看出问题出现在哪里,当前有时候可能需要进一步分析。

    参考资料:

    gc 查询java java 查看gc情况_mob6454cc61981e的技术博客_51CTO博客

    https://www.cnblogs.com/east7/p/16989436.html

    使用Linux的MAT分析工具分析超大dump文件(几GB)_准备起飞55的博客-CSDN博客

    Java Heap Dump 分析步骤 - 简书

    dump文件过大使用linux mat分析记录_dump文件太大怎么分析-CSDN博客

  • 相关阅读:
    专业140+总分400+华中科技大学824信号与系统考研经验华科华中大电子信息与通信工程,真题,大纲,参考书。
    【Git系列】02_Git分支
    儿童运动护齿市场现状及未来发展趋势分析
    免费简历制作神器
    C#基础总结二
    模组知识(1)-CRA-光学知识
    RobotFramework+Eclispe环境安装篇
    finereport开发者需要关注的问题
    [Vue3]自己封装Svg图标组件
    计算机视觉40例之案例06缺陷检测
  • 原文地址:https://blog.csdn.net/luostudent/article/details/133358413