请求的操作无法在使用用户映射区域打开的文件上执行_浅谈内存映射

a4088e8a0abb65c914c26ea5110383d1.png

写在前面:这是本人初入研究方法时做的笔记作为学习的输出,其中可能存在一些认知上的错误。若您有自己的见解,希望你可以在本文结尾给我留言或直接邮件联系我,与我讨论。

谢谢!

email:zhaos@nbjl.nankai.edu.cn

一. 内存映射(Memory-mapped)

内存映射(mmap)是一种内存映射文件的方法,即将一个文件或者其他对象映射到进程的地址空间,实现文件磁盘地址和应用程序进程虚拟地址空间中一段虚拟地址的一一映射关系。实现这样的映射关系后,进程就可以采用指针的方式读写操作这一段内存,而系统会自动回写藏页面到对应的文件磁盘上。应用程序处理映射部分如同访问主存。

36d7cf49f5edeed2ee207fcada1b3a3d.png
图1. 内存映射文件(图片来源https://www.cnblogs.com/huxiao-tee/p/4660352.html)

二. mmap内存映射原理

(1)线程启动映射过程,并在虚拟地址空间中为映射创建虚拟映射区域。

先在用户空间调用库函数mmap,并在进程当前进程的虚拟地址空间中,寻找一段空闲的满足要求的连续虚拟地址作为内存虚拟映射区域,对此区域初始化并插入进程的虚拟地址区域链表或树中。

(2)系统在内核空间调用内核函数mmap,实现文件物理地址和进程虚拟地址之间的一一映射关系。

(3)进程发起堆这片映射空间的访问

进程读写操作访问虚拟地址,查询页表,发现这一段地址并不在内存的物理页面上,因为虽然建立了映射关系,但是还没有将文件从磁盘移到内存中。由此发生缺页中断,内核请求从磁盘调入页面。调页过程先在交换缓存空间(swap cache)中查找,若没有则通过nopage函数把缺失页从磁盘调入内存。之后进程会对其做读写操作,若写操作改变了页面内容,一段时间后系统会自动回写脏页面到磁盘中。(修改过的脏页面不会立即更新到文件中,可以调用msync来强制同步,写入文件)

三. mmap和分页文件操作的区别

区别在于分页文件操作在进程访存时是需要先查询页面缓存(page cache)的,若发生缺页中断,需要通过inode定位文件磁盘地址,先把缺失文件复制到page cache,再从page cache复制到内存中,才能进行访问。这样访存需要经过两次文件复制,写操作也是一样。总结来说,常规文件操作为了提高读写效率和保护磁盘,使用了页缓存机制。这样造成读文件时需要先将文件页从磁盘拷贝到页缓存中,由于页缓存处在内核空间,不能被用户进程直接寻址,所以还需要将页缓存中数据页再次拷贝到内存对应的用户空间中。但mmap的优势在于,把磁盘文件与进程虚拟地址做了映射,这样可以跳过page cache,只使用一次数据拷贝。

另外我还想简单谈一下分页文件操作:

分页(Paging) :主存可以使用一部分磁盘空间,这样看上去主存的空间更大了。文件系统把磁盘分为固定大小的页(Page)。当不需要时,将分页由主存(通常是内存)移到辅助存储器;当需要时,再将数据取回,加载主存中。

分页文件技术能有助“大大地”降低整体及额外非必要的 I/O 次数,提高系统整体运作性能。但若运行所需物理内存过大,内存需要频繁的调入调出,页面不停的写入释放读取,回极大影响性能。这被称为系统颠簸。

参考文献:

[1] 认真分析mmap:是什么 为什么 怎么用

[2] 内存映射文件

[3] 分页

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值