JVM–基础–06–内存区域–直接内存
1、结构图
2、直接内存(堆外内存)
- 就是虚拟机以外的内存
- 本机直接内存的分配不会受到Java 堆大小的限制,受到本机总内存大小限制。
- 配置虚拟机参数时,不要忽略直接内存,防止出现OutOfMemoryError异常。
2.1、怎么使用
NIO(New Input/Output)类,引入了一种基于通道(Channel)与缓冲区(Buffer)的I/O 方式。
- NIO 首先 使用native函数库 直接分配 堆外内存(直接内存)
- NIO 然后 通过一个存储在Java堆中的DirectByteBuffer对象 作为这块内存的引用,对这块内存进行操作
优势:避免了在Java堆和Native堆中来回复制数据。
2.2、 直接内存(堆外内存)与堆内存比较
- 直接内存申请空间耗费更高的性能,当频繁申请到一定量时尤为明显
- 直接内存IO读写的性能要优于普通的堆内存,在多次读写操作的情况下差异明显
2.3、 直接内存使用场景
- 有很大的数据需要存储,它的生命周期很长
- 适合频繁的IO操作,例如网络并发场景
3、直接内存溢出 案例
package com.fei.zhou.day1;
import java.lang.reflect.Field;
import sun.misc.Unsafe;
public class DirectMemoryOOMTest {
/**
* VM Args:-Xms20m -Xmx20m -XX:MaxDirectMemorySize=10m
* @param args
*/
public static void main(String[] args) {
int i=0;
try {
Field field = Unsafe.class.getDeclaredFields()[0];
field.setAccessible(true);
Unsafe unsafe = (Unsafe) field.get(null);
while(true){
//申请内存1M
unsafe.allocateMemory(1024*1024);
i++;
}
} catch (Exception e) {
e.printStackTrace();
}finally {
System.out.println("分配次数:"+i);
}
}
}
结果:
分配次数:9639
Exception in thread "main" java.lang.OutOfMemoryError
at sun.misc.Unsafe.allocateMemory(Native Method)
at com.fei.zhou.day1.DirectMemoryOOMTest.main(DirectMemoryOOMTest.java:21)