1、MappedByteBuffer是DirectByteBuffer的子类
2、MappedByteBuffer使用的是mmap技术。MappedByteBuffer将文件映射为内存,也可能会被存储在虚拟内存里面,访问的时候通过缺页机制调进内存。
3、mmap可以实现两个进程之间共享数据 http://kenby.iteye.com/blog/1164700
4、mmap原理 http://blog.chinaunix.net/uid-26669729-id-3077015.html
5、MappedByteBuffer有一个文件释放问题,文件是在full gc的时候才会关闭 http://langgufu.iteye.com/blog/2107023
6、MappedByteBuffer能优化随机读(因为实际上会在内存里存放大量的页/块)
metaq在文件读写操作上做了一定的优化,使用内存映射的方式完成读写,替代了传统的IO操作,从而大大的减少了文件读写系统调用的次数,提升了IO的性能。
传统的文件访问:
- 系统调用打开文件,获取文件描述符
- 使用read write 系统调用进行IO
- 系统调用关闭文件
这种方式是非常低效的, 每一次I/O操作都需要一次系统调用。 另外, 如果若干个进程访问同一个文件, 每个进程都要在自己的地址空间维护一个副本, 浪费了内存空间
内存映射的方式:
- 打开文件,得到文件描述符。
- 获取文件大小
- 把文件映射成虚拟内存(mmap)
- 通过对内存的读写来实现对文件的读写(memset或memcpy)
- 卸载映射
- 关闭文件
首先建立好虚拟内存和磁盘文件之间的映射(mmap系统调用),当进程访问页面时产生一个缺页中断,内核将页面读入内存(也就是说把磁盘上的文件拷贝到内存中),并且更新页表指向该页面。
所有进程共享同一物理内存,物理内存中可以只存储一份数据,不同的进程只需要把自己的虚拟内存映射过去就可以了,这种方式非常方便于同一副本的共享,节省内存。经过内存映射之后,文件内的数据就可以用内存读/写指令来访问,而不是用Read和Write这样的I/O系统函数,从而提高了文件存取速度。package com.ydd.study.hello.mmap;import java.io.File;import java.io.IOException;import java.io.RandomAccessFile;import java.nio.ByteBuffer;import java.nio.MappedByteBuffer;import java.nio.channels.FileChannel;import java.nio.channels.FileChannel.MapMode;/** * 内存映射文件 * @author yunzhu.ydd * */public class MapedFile { private final String FILE_NAME = "D://mapedFile.txt"; private final long fileSize = 1024 * 1024;// 1M private FileChannel fileChannel; private MappedByteBuffer mappedByteBuffer; private File file; public MapedFile() throws IOException { this.file = new File(FILE_NAME); this.fileChannel = new RandomAccessFile(this.FILE_NAME, "rw") .getChannel(); //产生一定大小的文件,byte默认都为0。也就是说文件的byte都被初始化为0了 this.mappedByteBuffer = this.fileChannel.map(MapMode.READ_WRITE, 0, fileSize); } /** * 写 * @param str */ public void write(String str) { mappedByteBuffer.put(str.getBytes()); } /** * 读文件 */ public void getAll() { System.out.println("capacity:"+mappedByteBuffer.capacity()); for(int i=0;i