当前位置: 首页 > news >正文

内存映射文件原理探索(转载)

转载:http://blog.chinaunix.net/uid-20761674-id-3072683.html

一直都对内存映射文件这个概念很模糊,不知道它和虚拟内存有什么区别,而且映射这个词也很让人迷茫,今天终于搞清楚了。。。下面,我先解释一下我对映射这个词的理解,再区分一下几个容易混淆的概念,之后,什么是内存映射就很明朗了。

原理

首先,“映射”这个词,就和数学课上说的“一一映射”是一个意思,就是建立一种一一对应关系,在这里主要是只 硬盘上文件 的位置与进程 逻辑地址空间 中一块大小相同的区域之间的一一对应,如图1中过程1所示。这种对应关系纯属是逻辑上的概念,物理上是不存在的,原因是进程的逻辑地址空间本身就是不存在的。在内存映射的过程中,并没有实际的数据拷贝,文件没有被载入内存,只是逻辑上被放入了内存,具体到代码,就是建立并初始化了相关的数据结构(struct address_space),这个过程有系统调用mmap()实现,所以建立内存映射的效率很高。

 

图1.内存映射原理  

既然建立内存映射没有进行实际的数据拷贝,那么进程又怎么能最终直接通过内存操作访问到硬盘上的文件呢?那就要看内存映射之后的几个相关的过程了。

mmap()会返回一个指针ptr,它指向进程逻辑地址空间中的一个地址,这样以后,进程无需再调用read或write对文件进行读写,而只需要通过ptr就能够操作文件。但是ptr所指向的是一个逻辑地址,要操作其中的数据,必须通过MMU将逻辑地址转换成物理地址,如图1中过程2所示。这个过程与内存映射无关。

前面讲过,建立内存映射并没有实际拷贝数据,这时,MMU在地址映射表中是无法找到与ptr相对应的物理地址的,也就是MMU失败,将产生一个缺页中断,缺页中断的中断响应函数会在swap中寻找相对应的页面,如果找不到(也就是该文件从来没有被读入内存的情况),则会通过mmap()建立的映射关系,从硬盘上将文件读取到物理内存中,如图1中过程3所示。这个过程与内存映射无关。

如果在拷贝数据时,发现物理内存不够用,则会通过虚拟内存机制(swap)将暂时不用的物理页面交换到硬盘上,如图1中过程4所示。这个过程也与内存映射无关。

效率:

从代码层面上看,从硬盘上将文件读入内存,都要经过文件系统进行数据拷贝,并且数据拷贝操作是由文件系统和硬件驱动实现的,理论上来说,拷贝数据的效率是一样的。但是通过内存映射的方法访问硬盘上的文件,效率要比read和write系统调用高,这是为什么呢?原因是read()是系统调用,其中进行了数据拷贝,它首先将文件内容从硬盘拷贝到内核空间的一个缓冲区,如图2中过程1,然后再将这些数据拷贝到用户空间,如图2中过程2,在这个过程中,实际上完成了 两次数据拷贝 ;而mmap()也是系统调用,如前所述,mmap()中没有进行数据拷贝,真正的数据拷贝是在缺页中断处理时进行的,由于mmap()将文件直接映射到用户空间,所以中断处理函数根据这个映射关系,直接将文件从硬盘拷贝到用户空间,只进行了 一次数据拷贝 。因此,内存映射的效率要比read/write效率高。

 

 

图2.read系统调用原理

转载于:https://www.cnblogs.com/Przz/p/6501798.html

相关文章:

  • X-Frame-Options 响应头
  • Excel 总结
  • sklearn中随机森林的参数
  • CHIL-ORACLE-修改密码
  • itunes 无法构建版本问题
  • 继续过中等难度的题目
  • Spring Boot整合WebSocket介绍
  • [技术选型] Node.js
  • Spring cloud子项目
  • oracle 11gR2 ASM添加和删除磁盘
  • x-editable java 后台怎么写
  • java----数据结构与算法----集合元素的遍历:迭代器--------JavaAPI:java.util.Iterator+java.util.ListIterator...
  • Leetcode 423. Reconstruct Original Digits from English
  • JAVA加密类的使用
  • javascript数组去重复
  • 5分钟即可掌握的前端高效利器:JavaScript 策略模式
  • java B2B2C 源码多租户电子商城系统-Kafka基本使用介绍
  • Java 实战开发之spring、logback配置及chrome开发神器(六)
  • JS正则表达式精简教程(JavaScript RegExp 对象)
  • markdown编辑器简评
  • php ci框架整合银盛支付
  • PV统计优化设计
  • select2 取值 遍历 设置默认值
  • WordPress 获取当前文章下的所有附件/获取指定ID文章的附件(图片、文件、视频)...
  • 多线程 start 和 run 方法到底有什么区别?
  • 给初学者:JavaScript 中数组操作注意点
  • 利用阿里云 OSS 搭建私有 Docker 仓库
  • 排序(1):冒泡排序
  • 深度学习入门:10门免费线上课程推荐
  • 使用common-codec进行md5加密
  • 阿里云移动端播放器高级功能介绍
  • 哈罗单车融资几十亿元,蚂蚁金服与春华资本加持 ...
  • ​iOS实时查看App运行日志
  • ​插件化DPI在商用WIFI中的价值
  • # 飞书APP集成平台-数字化落地
  • #pragma once与条件编译
  • #Ubuntu(修改root信息)
  • (二)windows配置JDK环境
  • (附源码)springboot 房产中介系统 毕业设计 312341
  • (附源码)计算机毕业设计SSM智慧停车系统
  • (十八)三元表达式和列表解析
  • (原創) 是否该学PetShop将Model和BLL分开? (.NET) (N-Tier) (PetShop) (OO)
  • (转)h264中avc和flv数据的解析
  • (转)MVC3 类型“System.Web.Mvc.ModelClientValidationRule”同时存在
  • (转)原始图像数据和PDF中的图像数据
  • (转载)VS2010/MFC编程入门之三十四(菜单:VS2010菜单资源详解)
  • (状压dp)uva 10817 Headmaster's Headache
  • .NET Core 和 .NET Framework 中的 MEF2
  • .NET 反射 Reflect
  • @kafkalistener消费不到消息_消息队列对战之RabbitMq 大战 kafka
  • @PreAuthorize注解
  • @Transaction注解失效的几种场景(附有示例代码)
  • [ vulhub漏洞复现篇 ] Apache APISIX 默认密钥漏洞 CVE-2020-13945
  • [BUUCTF]-PWN:wustctf2020_number_game解析(补码,整数漏洞)
  • [BZOJ 4034][HAOI2015]T2 [树链剖分]