Java内存溢出问题排查分析

目录

前言

一、MAT(Memory Analyzer Tool)

二、软件初识

三、捕获dump文件

1、主动方式

2、被动方式

四、分析dump文件

总结


前言

项目运行过程中,我们可能会遇到Java内存溢出Out Of Memory。此时我们可以借助内存分析工具MAT(Memory Analyzer Tool),来定位是哪里出现了问题。


一、MAT(Memory Analyzer Tool

下载地址:Eclipse Memory Analyzer Open Source Project | The Eclipse Foundation

注意:JDK-8建议使用11版本,否则会提示版本不兼容

二、软件初识

Java内存溢出问题排查分析_第1张图片

解压后目录内有个MemoryAnalyzer.ini文件,该文件里面有个-Xmx参数。该参数表示最大内存占用量,默认为1024m。
建议修改为小于本机内存大小,大于要分析的dump文件大小
-startup
plugins/org.eclipse.equinox.launcher_1.5.0.v20180512-1130.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.win32.win32.x86_64_1.1.700.v20180518-1200
-vmargs
### -Xmx1024my原本默认为1024m,此处我修改为4096m
-Xmx4096m

三、捕获dump文件

        首先在程序中模拟出一段内存溢出的逻辑:

    @RequestMapping("/testOutOfMemory")
    @ResponseBody
    public void testOutOfMemory() throws Exception {
        String name = "Aikes";
        for (int i = 0; i < 10000000; i++) {
            name += name;
        }
        System.out.println(name);
    }

        然后启动项目,开始准备捕获dump文件。这里的捕获方式分为两种,一种是主动捕获,一种是被动捕获:

1、主动方式

        顾名思义,当内存溢出发生后,通过指令的方式手机当前应用程序下的内存使用情况。

1、通过(Linux) ps -ef|grep find 或者 (Dos)netstat -ano|findstr 查找java程序运行的PID

2、使用指令收集dump:jmap -dump:format=b,file=路径/heapdump.hprof  查到的PID

注意:主动获取dump文件必须是一出现内存异常就获取dump文件,这样获取的文件信息才比较准确。如果无法及时获取,推荐通过第二种方式获取dump文件。

Java内存溢出问题排查分析_第2张图片

Java内存溢出问题排查分析_第3张图片

2、被动方式

        该方式是启动Java服务时,增加额外参数。当程序发生内存溢出时自动收集dump文件:

1、-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/oom/heapdump.hprof

Java内存溢出问题排查分析_第4张图片

        配置好后,调用我们预先模拟的内存溢出接口

Java内存溢出问题排查分析_第5张图片

        稍等片刻控制台开始打印日志,提示出现内存溢出并且已经收集到dump文件到指定目录:

Java内存溢出问题排查分析_第6张图片

Java内存溢出问题排查分析_第7张图片

四、分析dump文件

        打开下载好的mat软件,通过file-open打开抓取到的dump文件(hprof文件)

Java内存溢出问题排查分析_第8张图片

        点击切换视图,可以看到内存占用百分之八十是因为这个线程,继续点开发现是一个超大的字符串"AikesAikesAikes...."

Java内存溢出问题排查分析_第9张图片

        此时我们已经发现了内存溢出的直接原因,接下来要寻找出现这个问题的代码在哪里。再返回到最初的大饼图,点击最下面的details。然后点击See stacktrace 堆叠追踪。

Java内存溢出问题排查分析_第10张图片

Java内存溢出问题排查分析_第11张图片

Java内存溢出问题排查分析_第12张图片

        这里可以看到完整的堆栈信息,里面可以发现我们增加模拟溢出代码的那个Java文件,并且爆发内存溢出的代码行也可以对上,至此溢出分析结束。

Java内存溢出问题排查分析_第13张图片


总结

        模拟的内存溢出针对性很强,并且我们抓取dump文件也很及时,所以在分析的时候很简单。实际使用过程中面对的陷阱很多,需要从诸多可能中排查幕后凶手。Mat工具功能还很多,目前只是粗略的使用,后续如果有新的发现会继续补充到博文中。

你可能感兴趣的:(Common,MAT,内存溢出,Java)