共享内存和 mmap 映射
共享内存本质上就是内核故意在两个进程的页表中映射了同一块物理内存。这里的物理内存是页缓存吗?和mmap映射的物理页面有什么区别
可以这样理解:共享内存和 mmap 映射普通文件,最终指向的物理内存都可以是 Page Cache,但它们的“身份”和使用方式有本质区别。
1. 共享内存(匿名映射)
创建方式
- System V:
shmget()+shmat() - POSIX:
shm_open()+mmap() - 直接
mmap()匿名映射:mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0)
物理内存的本质
- 不是 Page Cache,而是普通的匿名页(Anonymous Page)
- 这些物理页面不关联任何磁盘文件
- 内核通过
tmpfs内部实现(POSIX 共享内存),但平时不落盘
特点
- 没有文件后备(no backing file)
- 进程间共享的是同一块物理匿名页
- 如果系统内存紧张,匿名页会被交换到 Swap 分区,而不是回写文件
2. mmap 映射普通文件(文件映射)
创建方式
mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)
物理内存的本质
- 就是 Page Cache
- 物理页面直接关联磁盘文件
- 内核的 Page Cache 管理这些页面
特点
- 有文件后备(backing file)
- 多个进程映射同一文件时,共享同一批 Page Cache 页面
- 修改后会被回写到原文件(
MAP_SHARED模式)
3. 对比表
| 特性 | 共享内存(匿名映射) | mmap 文件映射 |
|---|---|---|
| 物理内存类型 | 匿名页(Anonymous Page) | Page Cache |
| 关联磁盘文件 | 无 | 有(backing file) |
| 换出目标 | Swap 分区 | 回写到原文件 |
| 持久化 | 重启后丢失 | 文件持久保存 |
| 内核管理 | 匿名页 LRU 链表 | Page Cache LRU 链表 |
| 典型用途 | 进程间通信 | 文件读写、动态库加载 |
4. 为什么共享内存不用 Page Cache?
Page Cache 的设计目的是缓存文件数据,它的生命周期和文件绑定:
- 文件被删除 → Page Cache 最终被回收
- 文件被修改 → Page Cache 标记为脏页,回写到磁盘
而共享内存的语义是:
- 独立于文件系统,进程退出后数据可能还在(System V 共享内存)
- 不需要回写到任何文件
- 用匿名页更符合“临时共享数据”的语义
5. 图示对比
共享内存(匿名映射):
进程A 页表 → 物理匿名页 ← 进程B 页表
↓ (内存紧张时)
Swap 分区
mmap 文件映射:
进程A 页表 → Page Cache 页面 ← 进程B 页表
↕
磁盘文件
总结
- 共享内存用的是匿名页,不是 Page Cache
mmap文件映射用的才是 Page Cache- 两者都能实现“多进程共享同一块物理内存”,但一个无文件后备,一个有文件后备
- 这就是为什么共享内存不能持久化,而
mmap文件映射可以

浙公网安备 33010602011771号