NIO MappedByteBuffer

MappedByteBuffer是一种效率低于零拷贝,但高于传统IO的IO操作。

算是一种弥补transferTo零拷贝时无法中间处理源数据的手段。。效率低于零拷贝,但高于使用普通堆外内存(DirectByteBuffer)

正文:

其实MappedByteBuffer是抽象类,而具体实现是DirectByteBuffer和DirectByteBufferR,并且是DirectBuffer的实现。也就是说,MappedByteBuffer其实用的也是堆外内存。只不过暂时现在我只知道MappedByteBuffer只能对文件进行映射。。把该文件指定偏移量范围的数据与堆外内存的偏移量一一对应(但数据并不会在创建MappedByteBuffer对象的时候立即加载到内存中)

一、MappedByteBuffer通过fileChannel.map方法创建。

(源码中MappedByteBuffer实现可能是java.nio.DirectByteBuffer或者java.nio.DirectByteBufferR两种,在fileChannel.map中通过反射创建对应的实例)

二、通过内存映射的方法访问硬盘上的文件,效率要比read和write系统调用高,这是为什么?

1、先了解一下虚拟内存

操作系统的虚拟内存是为了在真实内存不足时,使用硬盘的空间作为扩展。把部分硬盘空间地址映射为内存空间,分配了虚拟的内存地址,用户操作这些内存地址时,具体怎么操作是由操作系统管理。(比如读取数据时,发生缺页中断,这个时候再从磁盘读数据到内存中给用户使用,写数据时,也是先写到内存中,然后操作系统刷回磁盘)

所以:
我们要知道,MappedByteBuffer底层使用的是mmap()这个函数,其会把在磁盘中的该文件映射为虚拟内存。也就是说,操作这个文件可以像操作内存数据一样操作(即通过unsafe.getByte(address + 偏移量)获取指定内存的数据),不过获取数据时由于真实内存中不存在,所以会发生缺页中断,此时再从磁盘加载到内存中给用户使用。

(也就是数据在实际内存中不存在,此时就会把这个地址对应的数据从硬盘拷贝到内核缓冲区,再把这段内核缓冲区共享(映射)给用户空间(用户内存),用户进程可以直接操作通过mmap方式操作这块共享内存,而不用再从内核缓冲区把数据拷贝到用户空间才能进行操作了。write数据时,用户空间的程序将数据写入到这共享的这块内核区域,内核会自动将其同步到磁盘上)。
 

2、read()是系统调用,首先将文件从硬盘拷贝到内核空间的一个read缓冲区,再将这些数据拷贝到用户空间(堆外内存DirectByteBuffer),实际上进行了两次数据拷贝;

参考文章MappedByteBuffer:DirectByteBuffer与MappedByteBuffer_P19777的博客-优快云博客_mappedbytebuffer directbytebuffer

参考文章零拷贝:java NIO零拷贝、顺序读写、MappedByteBuffer_我叫周利东的博客-优快云博客_mappedbytebuffer 顺序写

参考文章DirectByteBuffer:https://blog.youkuaiyun.com/qq_36951116/article/details/87185240

MappedByteBuffer和DirectByteBuffer_什么啊什么Q的博客-优快云博客

其它相关文章:https://www.jianshu.com/p/f90866dcbffc

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值