前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >实战:OutOfMemoryError 异常(一) -- Java 堆溢出

实战:OutOfMemoryError 异常(一) -- Java 堆溢出

作者头像
Li_XiaoJin
发布2022-06-10 21:03:08
4020
发布2022-06-10 21:03:08
举报
文章被收录于专栏:Lixj's BlogLixj's Blog

关于Java 堆溢出的情况。学习中,记录一下具体思路。

Java 堆用于存储对象实例,只要不断地创建对象,并且保证 GC Roots 到对象之间有可达路径来避免垃圾回收机制清除这些对象,那么在对象数量到达最大堆的容量限制后就会产生内存溢出异常。

限制 Java 堆的大小为 20MB,不可扩展(将堆的最小值 -Xms 参数与最大值 -Xmx 参数设置Wie易语言即可避免自动扩展),通过参数 -XX:+HeapDumpOnOutOfMemoryError 可以让虚拟机在出现内存溢出异常时 Dump 出当前堆转储快照以便事后进行分析。

参考代码:

代码语言:javascript
复制
/**
 * -Xms20M -Xmx20M -XX:+HeapDumpOnOutOfMemoryError
 */
public class HeapOOM {
    static class OOMObject{

    }

    public static void main(String[] args) {
        List<OOMObject> list = new ArrayList<OOMObject>();
        while(true) {
            list.add(new OOMObject());
        }
    }
}

运行结果:

Java 堆内存的 OOM 异常是实际应用中常见的内存溢出异常情况。当出现 Java 堆内存溢出时,异常堆栈信息 “java.lang.OutOfMemoryError” 会跟着进一步提示 “Java heap space”。

要解决这个区域的异常,一般的手段是先通过内存映像分析工具对 Dump 出来的堆转储快照进行分析,重点是确认内存中的对象是否是必要的,也就是要先分清楚到底是出现了内存泄漏(Memory Leak)还是内存溢出(Memory Overflow)。

  • 如果是内存泄露,可进一步通过工具查看泄露对象到 GC Roots 的引用链。于是就能找到泄露对象是通过怎样的路径与 GC Roots 相关联并导致垃圾收集器无法自动回收它们的。掌握了泄露对象的类型信息及GCRoots引用链的信息,就可以比较准确地定位出泄露代码的位置。
  • 如果不存在泄露,换句话说,就是内存中的对象确实都还必须存活着,那就应当检查虚拟机的堆参数(-Xmx与-Xms),与机器物理内存对比看是否还可以调大,从代码上检查是否存在某些对象生命周期过长、持有状态时间过长的情况,尝试减少程序运行期的内存消耗。

以上是处理Java堆内存问题的简单思路。

报错后可以在目录下看到有快照文件

使用 jvisualvm 对其进行查看分析

输入命令 jvisualvm

找到文件后打开

查看

使用 jhat 对其进行查看分析

命令行中输入 jhat 文件路径/文件名

在浏览器中输入 http://localhost:7000/

书籍介绍:《深入理解Java虚拟机:JVM高级特性与最佳实践》

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可 Links: https://lixj.fun/archives/java堆溢出

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-01-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档