映射是个术语,指两个元素的集之间元素相互“对应”的关系,为名词。“映射”或者“投影”,

------------

       内存映射文件,是由一个文件到一块内存的映射。Win32提供了允许应用程序把文件映射到一个进程的函数 (CreateFileMapping)。内存映射文件与虚拟内存有些类似,通过内存映射文件可以保留一个地址空间的区域,同时将物理存储器提交给此区域,内存文件映射的物理存储器来自一个已经存在于磁盘上的文件,而且在对该文件进行操作之前必须首先对文件进行映射。

作用:使用内存映射文件处理存储于磁盘上的文件时,将不必再对文件执行I/O操作,使得内存映射文件在处理大数据量的文件时能起到相当重要的作用。


---如何内存映射-----https://www.cnblogs.com/wuchanming/p/4823444.html

     由于所有用户进程总的虚拟地址空间比可用的物理内存大很多,因此只有最常用的部分才与物理页帧关联。这不是问题,因为大多数程序只占用实际可用内存的一小部分。

     在将磁盘上的数据映射到进程的虚拟地址空间的时,内核必须提供数据结构,以建立虚拟地址空间的区域和相关数据所在位置之间的关联。例如,在映射文本文件时,映射的虚拟内存区必须关联到文件系统的硬盘上存储文件内容的区域。如图所示:

内存映射_内存映射

      当然,给出的是简化的图,因为文件数据在硬盘上的存储通常并不是连续的,而是分布到若干小的区域。内核利用address_space数据结构,提供一组方法从后备存储器读取数据。例如,从文件系统读取。因此address_space形成了一个辅助层,将映射的数据表示为连续的线性区域,提供给内存管理子系统。

按需分配和填充页称为按需调页法。它基于处理器和内核之间的交互,使用的各种数据结构如图所示:

内存映射_内存映射_02

过程如下:

CPU将一个虚拟内存空间中的地址转换为物理地址,需要进行两步(如下图):

首先,将给定一个逻辑地址(其实是段内偏移量,这个一定要理解!!!),CPU要利用其段式内存管理单元,先将为个逻辑地址转换成一个线程地址,

其次,再利用其页式内存管理单元,转换为最终物理地址。

     内存映射_内存映射_03

 这样做两次转换,的确是非常麻烦而且没有必要的,因为直接可以把线性地址抽像给进程。之所以这样冗余,Intel完全是为了兼容而已。

  • 进程试图访问用户地址空间中的一个内存地址,利用上面的线性地址去查找页表,确定对应的物理地址,但使用的页表无法确定物理地址(物理内存中没有关联页)

  • 处理器接下来触发一个缺页异常,发送到内核。

  • 内核会检查负责缺页区域的进程地址空间数据结构,找到适当的后备存储器,或者确认该访问实际上是不正确的(未映射,未使用)

  • 分配物理内存页,并从后备存储器读取所需数据填充。

  • 借助于页表将物理内存页并入到用户进程的地址空间,应用程序恢复执行。

这些操作对用户进程是透明的。换句话说,进程不会注意到页是实际在物理内存中,还是需要通过按需调页加载。

 

内存映射_内存映射_04

在整个过程中可能需要解决以下几个问题:

1)系统如何感知进程当前所需页面不在主存(页表机制);
2)当发现缺页时,如何把所缺页面调入主存(缺页中断机构);
3)在置换页面时,根据什么策略选择欲淘汰的页面(置换算法)。

页表机制

 

内存映射_内存映射_05

状态位(中断位):标识该页是否在内存(0或1);
访问位:标识该页面的近来的访问次数或时间(换出);
修改位:标识此页是否在内存中被修改过;
外存地址:记录该页面在外存上的地址,即(外存而非内存的)物理块号。

缺页中断机制

程序在执行时,首先检查页表,当状态位指示该页不在主存时,则引起一个缺页中断发生,其中断执行过程与一般中断相同:
保护现场(CPU环境);
中断处理(中断处理程序装入页面);
恢复现场,返回断点继续执行。

置换算法

FIFO

LRU

LFU

 

总结:内存映射就是将一个文件映射到内存中,使得应用程序可以将一段文件映射到一个进程中,这样这个内存映射文件处理存储于磁盘上的文件时,将不必再对文件执行I/O操作,对处理大数据量内存时有作用。

好处:

一方面,用来加载exe和dll文件,可以节省页文件空间和应用程序启动所需的时间;
另一方面,用于访问磁盘上的数据文件,可以减少文件I/O,并且不必对文件进行缓存;
此外还可以实现多个进程间的数据共享。