在之前的文章中我们了解到NIO中堆外内存的实现类是java.nio.DirectByteBuffer
和java.nio.MappedByteBuffer
。本文中我们也通过这两个类来分析NIO中堆外内存的实现。
如何从Java code获取堆外内存
我们都知道Java code是运行在JVM进程所管理的内存上的,而堆外内存是JVM进程所管控的内存之外的,那么如何从Java代码中获取对外内存呢?在Java层面管理堆外内存的实现类是DirectByteBuffer
。
DirectByteBuffer
继承自MappedByteBuffer
,MappedByteBuffer
是个抽象类,继承自ByteBuffer
,ByteBuffer
继承了Buffer
类。ByteBuffer
提供了一个allocateDirect
方法来分配堆外内存:
public static ByteBuffer allocateDirect(int capacity) {
return new DirectByteBuffer(capacity);
}
因此从Java code角度只需要ByteBuffer buffer = ByteBuffer.allocate(1024)
即可获取到一块堆外内存,调用ByteBuffer
相关api就可以操作这块堆外内存了。
此外java.nio.channels.FileChannel
也提供了一个获取堆外内存的方法:
public abstract MappedByteBuffer map(MapMode mode,
long position, long size) throws IOException;
该方法用于将一个文件映射到一块堆外内存。此后操作这块内存就像直接操作文件一样,map
一般通过如下方式使用:
// 创建一个文件
FileInputStream fis = new FileInputStream("NonHeapMem.txt");
FileChannel fileChannel = fis.getChannel();
MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, fileChannel.size());
获取到mappedByteBuffer
对象后就可以调用MappedByteBuffer
相关api直接操作文件了。