11_直接内存
Posted root_zhb
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了11_直接内存相关的知识,希望对你有一定的参考价值。
1、概述
- 不是虚拟机运行时数据区的一部分,也不是《Java虚拟机规范》中定义的内存区域
- 直接内存是Java堆外的、直接向系统申请的内存区间
- 来源于NIO,通过存在堆中的DirectByteBuffer操作Native内存
- 通常,访问直接内存的速度会优于Java堆。即读写性能高.
- 因此出于性能考虑,读写频繁的场合可能会考虑使用直接内存。
- Java的NIO库允许Java程序使用直接内存,用于数据缓冲区
2、代码
/**
* IO NIO (New IO / Non-Blocking IO)
* byte[] / char[] Buffer
* Stream Channel
*
* 查看直接内存的占用与释放
*/
public class BufferTest {
private static final int BUFFER = 1024 * 1024 * 1024;//1GB
public static void main(String[] args){
//直接分配本地内存空间
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BUFFER);
System.out.println("直接内存分配完毕,请求指示!");
Scanner scanner = new Scanner(System.in);
scanner.next();
System.out.println("直接内存开始释放!");
byteBuffer = null;
System.gc();
scanner.next();
}
}
3、OOM与内存大小设置
- 直接内存大小可以通过 -XX:MaxDirectMemorySize=10m 设置,如果不指定,默认与堆的最大值 -Xmx参数值一致
- 直接内存OOM错误
- 简单理解: java process memory = java heap + native memory (栈和程序计数器等可忽略)
4、优缺点
-
优点
①. 减少了垃圾回收
堆外内存是直接受操作系统管理(不是JVM)。这样做能保持一个较小的堆内内存,以减少垃圾收集对应用的影响。②. 提升IO速度
堆内内存由JVM管理,属于“用户态”;而堆外内存由OS管理,属于“内核态”。如果从堆内向磁盘写数据时,数据会被先复制到堆外内存,即内核缓冲区,然后再由OS写入磁盘,使用堆外内存避免了这个操作。 -
缺点
缺点就是没有JVM协助管理内存,需要我们自己来管理堆外内存,防止内存溢出。为了避免一直没有FULL GC,最终导致物理内存被耗完。我们会指定直接内存的最大值,通过-XX:MaxDirectMemerySize来指定,当达到阈值的时候,调用system.gc来进行一次full gc,把那些没有被使用的直接内存回收掉。
以上是关于11_直接内存的主要内容,如果未能解决你的问题,请参考以下文章