3.2.7 内存映射文件

内存映射文件(Memory-Mapped Files, MMF) 是一种极其高效的 I/O 处理机制。它允许操作系统将磁盘上的文件内容直接映射到进程的虚拟地址空间中。

通过这种方式,程序可以像访问内存中的数组或结构体一样,直接读写文件,而不需要显式地调用 readwrite 函数。


1. 核心原理

内存映射文件的核心在于利用了操作系统的虚拟内存管理机制

  1. 映射(Mapping): 当你调用 mmap(Linux)或 CreateFileMapping(Windows)时,OS 并不会立即将整个文件读入内存。它只是在进程的页表中划出一块区域,并将其指向文件在磁盘上的位置。
  2. 缺页中断(Page Fault): 当程序第一次访问这段内存地址时,会触发缺页中断。
  3. 调入内存: 操作系统捕获到中断后,自动将该地址对应的文件数据块(通常是 4KB 的页框)从磁盘读取到物理内存中。
  4. 同步(Sync): 对这块内存的修改会被标记为“脏页”,并在合适的时机(或手动调用同步指令时)写回磁盘。

2. 内存映射文件 vs. 标准文件 I/O

传统的 read/write 方式涉及到数据的多次拷贝,而 MMF 则大幅精简了这一过程。

特性标准文件 I/O (read/write)内存映射文件 (mmap)
拷贝次数至少 2 次(磁盘 \to 内核缓冲 \to 用户缓冲)通常 1 次(磁盘 \to 用户可访问的内核物理页框)
系统调用频繁调用 read/write,开销大仅在映射和解除映射时调用,访问时无开销
编程模型流式处理,需要维护偏移量指针操作,像访问内存一样随机访问
共享性不同进程拥有独立的副本多个进程可映射同一文件,实现极速共享内存

3. 主要优势

  • 性能优异: 减少了用户态与内核态之间的数据拷贝和上下文切换,特别是处理大型文件时优势明显。
  • 简化编程: 不需要频繁处理缓冲区(Buffer)的分配、管理和同步逻辑。
  • 进程间通信 (IPC): 这是实现共享内存最常用的手段。两个或多个进程映射同一个物理文件,一个进程修改了内存内容,另一个进程能立即看到。
  • 持久化支持: 即使程序异常退出,由于数据是映射在内核管理的页缓存(Page Cache)中,操作系统仍有机会将脏页刷回磁盘。

4. 局限性与挑战

  • 地址空间限制: 在 32 位系统中,虚拟地址空间只有 4GB,映射巨大的文件(如 100GB 的视频)会耗尽地址空间。但在 64 位系统中这已不再是问题。
  • 页对齐要求: 内存映射通常以页(4KB)为单位。如果文件大小不是页的整数倍,末尾部分会产生一定的内部碎片。
  • 指针管理: 如果映射被解除(unmap)后继续访问原指针,会导致段错误(Segmentation Fault)。

发表评论