mmap:文件什么时候会变成程序地址空间里的一扇窗?
TL;DR
mmap 将文件映射进进程虚拟地址空间,程序像访问内存一样按页访问文件,同时把缺页装载、缓存与回收交给操作系统。
mmap 将文件映射进进程虚拟地址空间,程序像访问内存一样按页访问文件,同时把缺页装载、缓存与回收交给操作系统。

文件通常被理解为磁盘上的一串字节,程序要读它,往往先调用 read 把内容复制到用户态缓冲区。mmap(memory mapping,内存映射)提供了另一种视角:把文件的一段内容映射到进程的虚拟地址空间,让程序像访问内存一样访问文件。
可以把文件想成仓库,把进程地址空间想成一张城市地图。mmap 不是把整个仓库立刻搬到城市,而是在地图上预留一块“对应区域”。程序第一次触碰某一页时,操作系统再通过缺页机制把相应文件页装入内存,并建立虚拟地址到物理页的映射。没访问的部分可以继续留在磁盘上。
这种方式很适合随机访问大型文件、共享内存、加载动态库和构建文件缓存。多个进程还可以映射同一文件的页面,让操作系统在物理内存层面复用缓存。对程序来说,索引结构可以直接用指针或偏移访问,避免显式地管理每次 read 的缓冲区。
代价是,文件访问的延迟被隐藏到页面错误里,第一次触碰某页可能触发磁盘 I/O;映射区域也可能因为内存压力被换出。文件被截断后继续访问映射区会导致异常,多个进程写同一映射还涉及可见性、同步和持久化边界。mmap 也不等于永久驻留内存,更不保证每一次访问都比 read 快。
理解 mmap 的关键是区分虚拟地址和物理数据:程序拿到的是一个地址视图,操作系统负责在背后按页装载、缓存和回收。它把文件系统与虚拟内存连接起来,使文件、共享内存和进程地址空间可以用同一种访问模型协作。
映射还分为共享和私有等不同语义。共享映射可以让写入对其他映射者可见,并最终通过同步机制落回文件;私有映射则常借助写时复制,让进程拥有自己的修改。选择哪一种,取决于应用要的是跨进程通信、文件持久化,还是高效读取,而不能只看 API 名字里有“memory”。
资料来源:Linux mmap(2) 手册



