内存映射
内存映射
内存映射是在进程的虚拟地址空间中创建一个映射
内存映射分类
内存映射分为两类:
- 文件映射:把文件的一个区间映射到进程的虚拟地址空间,数据源为设备上的文件。
- 匿名映射:把物理内存映射到进程的虚拟地址空间,没有数据源。
在进程的虚拟地址空间中,代码段和数据段属于文件映射,堆、栈属于匿名映射。
内存映射的原理
- mmap()会返回一个指针,它指向进程虚拟地址空间中的一个地址,这样以后,进程无需再调用read或write对文件进行读写,而只需要通过ptr就能够操作 文件。但是ptr所指向的是一个逻辑地址,要操作其中的数据,必须通过MMU将逻辑地址转换成物理地址,如图1中过程2所示。这个过程与内存映射无关。
- 建立内存映射并没有实际拷贝数据,这时,MMU在地址映射表中是无法找到与ptr相对应的物理地址的,也就是MMU失败,将产生一个缺页中断,缺 页中断的中断响应函数会在swap中寻找相对应的页面,如果找不到(也就是该文件从来没有被读入内存的情况),则会通过mmap()建立的映射关系,从硬 盘上将文件读取到物理内存中,如图1中过程3所示。这个过程与内存映射无关。
- 如果在拷贝数据时,发现物理内存不够用,则会通过虚拟内存机制(swap)将暂时不用的物理页面交换到硬盘上,如图1中过程4所示。这个过程也与内存映射无关。
内存映射和读写文件的效率
- read文件时,首先将文件中的内容读到内核空间的内存缓存区中,再将数据从内核空间拷贝到用户空间,中间经历了两次数据拷贝。
- 内存映射后,将文件映射到用户空间的一个逻辑地址中,此时只需要将文件拷贝到内存中这一次拷贝。