JVM学习笔记——本机直接内存溢出

作者: 南宫知晓 | 来源:发表于2019-01-29 18:04 被阅读21次
一、JVM直接内存

直接内存并不是虚拟机运行时数据区的一部分,也不是Java 虚拟机规范中定义的内存区域。在JDK1.4 中新加入了NIO(New Input/Output)类,引入了一种基于通道(Channel)与缓冲区(Buffer)的 I/O 方式,它可以使用 native 函数库直接分配堆外内存,然后通过一个存储在Java堆中的 DirectByteBuffer 对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了在 Java 堆和 Native 堆中来回复制数据。

  • 本机直接内存的分配不会受到Java 堆大小的限制,受到本机总内存大小限制
  • 直接内存也可以由 -XX:MaxDirectMemorySize 指定
  • 直接内存申请空间耗费更高的性能
  • 直接内存IO读写的性能要优于普通的堆内存

当我们的需要频繁访问大的内存而不是申请和释放空间时,通过使用直接内存可以提高性能。

二、直接内存溢出测试

测试代码如下,运行时添加参数 -Xmx20M -XX:MaxDirectMemorySize=10M 设置降低直接内存的空间来加快异常的抛出

package test_DirectMemoryOOM;

import java.lang.reflect.Field;
import sun.misc.Unsafe;

public class DirectrMemoryOOM {
    private static final int _1M = 1024 * 1024;
    
    public static void main(String[] args) throws Exception {
        Field unsafeField = Unsafe.class.getDeclaredFields()[0];
        unsafeField.setAccessible(true);
        @SuppressWarnings("restriction")
        Unsafe unsafe = (Unsafe) unsafeField.get(null);
        while(true) {
            unsafe.allocateMemory(_1M);
        }
    }

}

对于在eclipse上,使用sun.misc.Unsafe会出现找不到类的报错,这是出于安全考虑做的限制。可以通过以下方法解决:

Project > properties > Java Compilee > Errors/Warnings :

eclipse配置.png

运行结果:

Exception in thread "main" java.lang.OutOfMemoryError
   at sun.misc.Unsafe.allocateMemory(Native Method)
   at test_DirectMemoryOOM.DirectrMemoryOOM.main(DirectrMemoryOOM.java:15)

不断申请1M的空间,最终会耗尽内存抛出 OutOfMemoryError 异常。

三、注意

由于申请直接内存不由虚拟机管理,所以由此导致的 OOM 是不会在 Heap Dump 文件中看出明显的异常。当 OOM 后发现 Dump 文件很小同时程序直接或间接使用了 NIO ,就可以考虑一下这方面的原因。

关于 Heap Dump 的内容可以在 JVM学习笔记——jhat的使用 了解

相关文章

  • JVM学习笔记——本机直接内存溢出

    一、JVM直接内存 直接内存并不是虚拟机运行时数据区的一部分,也不是Java 虚拟机规范中定义的内存区域。在JDK...

  • Mac环境使用JMeter内存溢出

    Mac上JVM限制了线程数为2048,调整内存无效,建议使用Windows或Linux jmeter本机内存溢出如...

  • 无标题文章

    什么情况下出现本机直接内存溢出?怎么解决? 产生原因 jdk本身很少操作直接内存,而直接内存(DirectMemo...

  • Java开发

    JVM 内存溢出实例 - 实战 JVM(二) 介绍 JVM 内存溢出产生情况分析Java - 注解详解 详细介绍 ...

  • JVM、并发编程、函数式编程思维导图分享,简单明了

    一、JVM 1. 运行时数据区域 线程私有 线程共享 2. 溢出 堆溢出 栈溢出 方法区溢出 直接内存溢出 3. ...

  • java 基础 - 收藏集 - 掘金

    Java 学习过程|完整思维导图 - 后端 - 掘金JVM 1. 内存模型( 内存分为几部分? 堆溢出、栈溢出原因...

  • JVM学习笔记(3)-垃圾收集算法

    JVM学习笔记(1)-内存管理机制 JVM学习笔记(2)-内存分配与回收 垃圾收集算法 JVM垃圾收集算法有四种:...

  • JVM

    简介 Jvm 系列一:Java类的加载机制Jvm系列二:JVM内存结构 --内存泄漏与内存溢出Jvm系列三:GC算...

  • JVM之内存模型以及各种溢出异常

    近期学习了JVM,借此整理一下JVM有关的内存模型和各种内存溢出。 运行时数据区域 要理解Java的内存模型,作者...

  • HashMap内存内存溢出问题

    内存溢出 内存溢出就是内存超出了JVM虚拟机的内存容量,导致出现了java.lang.OutOfMemoryErr...

网友评论

    本文标题:JVM学习笔记——本机直接内存溢出

    本文链接:https://www.haomeiwen.com/subject/nloxsqtx.html