Skip to content

内存映射

操作系统 通过 mmap 系统调用进行操作,mmap 操作可以将一个文件 fd 中的数据进行加载,将其数据映射到虚拟内存空间中,当读写这些内存的时候,就相当于读写这个文件的内容,可以大幅度提高文件读写的性能,同时,内存映射还支持更多的功能。

直接映射

操作系统可以直接访问物理内存,但是由于 CPU 访问内存必须经历 MMU,所以操作系统在访问物理内存的时候依然需要进行映射,由此形成内核地址空间。操作系统内核态地址直接使用线性映射即可。

虚拟内存映射

在进程申请内存的时候,操作系统并不会立即建立虚拟内存页到真实物理页的映射关系,只有当进程真正去访问某个虚拟页的时候,并触发缺页异常时,操作系统才会开始为这个页去映射真实的物理页。

共享内存

内存映射

物理内存和虚拟内存之间存在映射关系:

  • 映射以一块连续的内存为单位(通常为4000 Byte)
  • 一块虚拟内存对应一块真实的物理内存
  • 这个单位称为内存分页
  • 操作系统通过页表(多级数组数据结构)维护映射关系

当进程创建时,操作系统为进程创建页表,维护进程的虚拟内存到物理内存的映射。当应用程序通过系统调用进行内存分配时:

  1. 调用操作系统的封装函数
  2. 操作系统分配物理内存
  3. 执行内存映射操作
  4. 返回指向虚拟内存的指针

自定义内存映射

c
#include <sys/mman.h>
/**
 * @param addr 可以是 NULL,由操作系统自行分配
 * @param fd 需要映射的文件
 * @param offset 偏移量
 */
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);

mmap函数将文件fd中的内容映射到当前进程的内存空间中addr位置处,大小为length,通过prot参数控制内存访问权限,通过flags提供更多配置选项。