JVM

JVM那点事-内存溢出如何处理(1)——MAT工具的下载使用

2019-03-02  本文已影响58人  小胖学编程

哈喽,大家好,本期这一系列,咱们聊一下发生OOM咱们应该怎么处理。

读者们可以去搬运工小胖——MAT工具下载地址里面下载Eclipse Memory Analyzer工具。有兴趣的小伙伴可以搬运工小胖——使用Eclipse Memory Analyzer的技巧看一波lan大佬怎么分析的。资源先摆上来,方便大家的使用。

1. 生成dump文件

小胖采用的是idea,毕竟网上Eclipse使用MAT的攻略蛮多的。首先要去配置JVM参数。

配置JVM参数入口.png

-Xmx20m -Xms5m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:/b.dump
这里咱们说一下参数的含义。
-Xmx20m 最大堆的大小20m;
-Xms5m最小堆的大小5m;
-XX:+HeapDumpOnOutOfMemoryError可以让虚拟机在出现内存溢出时Dump出当前内存堆存储快照以便我们分析;
XX:HeapDumpPath=d:/b.dump存放 dump文件的地址。

配置JVM参数.png

书写测试类代码:

public class TestJVM {
    static class OOMObject {
        private String name;
        public OOMObject(String name) {
            this.name = name;
        }
    }
    public static void main(String[] args) {
        List<OOMObject> list = new ArrayList<>();
        while (true) {
            list.add(new OOMObject("小胖同学"));
        }
    }
}

运行代码,发现出现JVM异常:

OOM异常.png

2. 使用MAT加载dump日志

双击exe文件,打开MAT文件:

打开mat文件.png

点击File——>Open Heap Dump...——>选择生成的dump文件
(点击之后,要在下面文本框中搜索文件的)

加载dump文件.png

3. 使用MAT分析dump文件

3.1 浅堆和保留堆的概念

首先,在这里,要引入两个概念:

Shallow Size( ['ʃæləʊ] 浅 ):对象本身占用内存的大小,不包括它的引用对象。
针对非数组类型对象,它的大小就是对象与他所有成员变量大小总和。
针对数组类型的对象,它的大小就是数组元素对象的大小总和。

Retained Size( [rɪ'teɪned] 保留):就是当前对象被GC后,从Heap上总共能释放掉的内存。不过,释放的时候还要排除被GC Roots直接或者间接引用的对象。

Retained Size.png

A对象的Retained Size就是A对象的Shallow Size大小。
B对象的Retained Size就是A对象的Shallow Size大小+C对象大小。
因为D对象是被GC直接引用,故不能释放。

MAT下理解Shallow size和Retained Size.png

我们可以看到main线程下,自身的内存Shallow Size占用是120B,但是Retained Size,GC后可释放的对象。几乎占满堆内存。

3.2 分析Dominator Tree

我们可以通过Dominator Tree['dɒmɪneɪtə] 支配者菜单选项进行排查。Dominator Tree提供了一个列表。Dominator Tree:对象之间dominator关系树。如果从GC Root到达Y的的所有path都经过X,那么我们称X dominates Y,或者X是Y的Dominator

分析Dominator Tree.png

3.3 分析Histogram 柱状图

histogram ['hɪstəɡræm]如果需要查询特性的某个类,我们可以在第一行输入类名或者关键词进行正则匹配查找。我们可以找到疑似内存泄露的类。

比较重要的一点,选中疑似类,右键出来选中List Objects,得到的结果再右键选中"Paths to GC Roots",我们可以通过它快速找到GC ROOT,如果存在GC ROOT,它就不会被回收。

Histogram 直方图.png

3.4 Path to GC Roots

查看一个对象到RC Roots的引用链 通常在排查内存泄漏的时候,我们会选择exclude all phantom/weak/soft etc.references,意思是查看排除虚引用/弱引用/软引用等的引用链,因为被虚引用/弱引用/软引用的对象可以直接被GC给回收,我们要看的就是某个对象否还存在Strong 引用链(在导出HeapDump之前要手动出发GC来保证),如果有,则说明存在内存泄漏,然后再去排查具体引用。

Path to GC Roots.png

其它重要选项:

  1. List objects :
    with incoming references 引用到该对象的对象
    with outcoming references 被该对象引用的对象
  2. Show objects by class :
    incoming references 引用到该对象的对象
    outcoming references 被该对象引用的对象

引用ListArray的对象with incoming references

with incoming references.png

ArrayList引用的对象with outcoming references

引用的对象.png

文章参考:https://bjyzxxds.iteye.com/blog/1532937
https://blog.csdn.net/Jin_Kwok/article/details/80326088

上一篇下一篇

猜你喜欢

热点阅读