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

实战:OutOfMemoryError 异常(四) -- 本机直接内存溢出

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

关于本机直接内存溢出的情况。

DirectMemory 容量可通过 -XX:MaxDirectMemorySize 指定,如果不指定,则默认与 Java 堆最大值(-Xmx 指定)一样,以下代码中越过了 DirectByteBuffer 类,直接通过反射获取 Unsafe 实例进行内存分配(Unsafe 类的 getUnsafe() 方法限制了只有引导类加载器才会返回实例,也就是设计者希望只有 rt.jar 中的类才能使用 Unsafe 的功能)。因为,虽然使用 DirectByteBuffer 分配内存也会抛出内存溢出异常,但它抛出异常时并没有真正向操作系统申请分配内存,而是通过计算得知内存无法分配,于是手动抛出异常,真正申请分配内存的方法是 unsafe.allocateMemory()。

代码如下:

使用unsafe分配本机内存

代码语言:javascript
复制
/**
 * -Xmx20M -XX:MaxDirectMemorySize=10M
 */
public class DirectMemoryOOM {
    private static final int _1Mb = 1024*1024;

    public static void main(String[] args) throws Exception{
        Field unSafeField = Unsafe.class.getDeclaredFields()[0];
        unSafeField.setAccessible(true);
        Unsafe unsafe = (Unsafe)unSafeField.get(null);
        while (true) {
            unsafe.allocateMemory(_1Mb);
        }
    }
}

运行结果:

由 DirectMemory 导致的内存溢出,一个明显的特征是在 Heap Dump 文件中不会看见明显的异常,如果在排查问题时发现 OOM 之后 Dump 文件很小,而程序中又直接或间接使用了NIO,那就可以考虑检查一下是不是这方面的原因。

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

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可 Links: https://lixj.fun/archives/实战outofmemoryerror异常四--本机直接内存溢出

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

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

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

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

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