堆内存溢出定位(Heap Dump)

Java堆内存溢出分析与定位工具
本文介绍了如何使用MAT和VisualVM工具来定位Java堆内存溢出问题。通过配置JVM参数获取Heap Dump,然后在MAT中分析泄露嫌疑人,以及在不同版本的VisualVM中查看对象引用和调用栈信息,从而找出内存泄漏的源头。同时讨论了内存溢出的场景和业务代码中可能的内存溢出改造策略。

配置 jvm 参数,内存溢出时会自动HeapDump(指定 dump 文件路径是可选的)

-Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home

或者用 jmap

jmap -dump:format=b,file=<filename.hprof> <pid>

必要时将dump文件从容器中拷贝到物理机

# docker cp <container_name>:<container_path>  <local_path>

docker cp 4d09feaf6483:/home/java_pid8.hprof /work
# kubectl cp default/POD_NAME:bin/FILE_NAME /Users/username/FILE_NAME

kubectl cp default/docker-sample-799db6c8d7-mqwww:/home/java_pid8.hprof /home/K8S/java_pid8.hprof

MAT(Memory Analyzer Tool) 定位堆内存溢出问题

下载安装 MAT(Memory Analyzer Tool),这个软件是 eclipse 基金会搞的。

打开 MAT -> File -> Open Heap Dump -> 选择对应 .hprof 文件

MAT 1

点击查看 leak suspects(泄露嫌疑人),分析内存泄露

MAT 2

点击这个 Problem Suspect1Details,在 Shortest Paths To the Accumulation Point (到达累积点的最短路径)点击 java.lang.Object[360145] ,选择 Lists objects -> with incoming references,查看这个对象被引用情况。

MAT 3

MAT 4

可以看到,是被 oomList 引用了,所以就会怀疑是 oomList 对象导致的内存溢出,然后去对应代码里查看。

/**
 * 堆内存溢出
 *
 * -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError
 */
@Component
public class HeapOOMService {

    private AtomicInteger index = new AtomicInteger(0);

    private List<User> oomList = new ArrayList<>();

    public void heapOOM() {
        while (true) {
            oomList.add(new User(index.getAndAdd(1)));
        }
    }

    private static class User {
        private int id;

        public User(int id) {
            this.id = id;
        }
    }
}

此外,点击 See stacktrace 可以查看调用栈信息,从调用栈信息中,也可以找到是哪里出问题。

MAT5

MAT6

VisualVM 定位堆内存溢出问题

VisualVM JDK8 内置,直接输入命令 jvisualvm 即可,JDK11以后需要下载

JDK8版本 VisualVM

打开 VisualVM -> File -> load -> 选择对应 .hprof 文件 -> 点击类 -> 在实例数最多的类名上右击 -> 选择在实例视图中展示 -> 查看引用

VisualVM1

VisualVM2

VisualVM3

新版本 VisualVM 2.1.5(JDK11不内置了)

http://visualvm.github.io/download.html

打开 VisualVM -> File -> load -> 选择对应 .hprof 文件 -> Instances by Size -> 右击 java.lang.Object 数组 -> 点击 Open in New Tab -> 展开 references

VisualVM4

VisualVM5

堆内存溢出的场景

  • 内存泄露
  • 非内存泄露

业务代码中可能的内存溢出改造

pageSize 不做限制可以无限大的话,可能导致内存溢出。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值