本文主要概要说明对文件的**mmap**操作和**read/write**操作,linux内核的差异。
文件页缓存
在 Linux 里,文件页缓存(page cache)是内核用来加速文件 I/O 的一块内存缓存机制,它把磁盘文件的数据页缓存在内存中,以减少磁盘访问。
1. 页缓存的基本概念
- 当用户进程调用
read()读取文件时,内核会检查该文件对应的数据是否已经在 页缓存 中:- 如果在缓存中(cache hit),直接从内存返回给用户(将页缓存中数据拷贝到用户空间),无需访问磁盘。
- 如果不在缓存中(cache miss),内核会触发缺页,读取磁盘数据放入页缓存,再把数据拷贝给用户。
- 当用户调用
write()时,数据先写入页缓存并标记为“脏页”(dirty page),然后由内核的回写机制(如pdflush/writeback)异步地刷回磁盘,而不是立刻写磁盘。
所以,文件页缓存是文件系统层面对磁盘文件数据的内存缓存。
2. 页缓存与匿名页的区别
- 匿名页:进程堆、栈等不映射文件的内存,由 swap 管理(可能换出到 swap 分区)。
- 文件页缓存:由文件映射到内存的页,可以丢弃(反正还能从磁盘文件重新读出来),所以它和 swap 不一样。
3. 页缓存的存储单位
- 以 页(page,通常 4KB) 为基本单位。
- 文件的数据会被切分成一个个页,并缓存在内核的 radix tree / xarray(数据结构)中,便于快速索引“文件偏移 → 内存页”。
4. 页缓存的作用
- 加速文件访问:减少磁盘 IO。
- 合并写操作:延迟写回,提高磁盘写效率。
- 内存回收友好:如果内存紧张,脏页刷回磁盘,干净页直接丢弃即可。
5. 相关命令
可以通过命令 <font style="color:rgb(15, 17, 21);background-color:rgb(235, 238, 242);">free -h</font> 或 <font style="color:rgb(15, 17, 21);background-color:rgb(235, 238, 242);">cat /proc/meminfo</font> 查看 <font style="color:rgb(15, 17, 21);background-color:rgb(235, 238, 242);">cached</font> 的值,它显示了当前系统中文页缓存的大小。
总结
文件页缓存是 Linux 内核用内存缓存磁盘文件数据的一种机制,用来加快文件读写,减少磁盘 I/O。它是进程文件访问和底层块设备之间的重要中间层。
文件mmap vs read/write
1. mmap 的情况
- 当调用
mmap(file)时,内核并不会立刻把文件的数据拷贝到用户空间。 - 它只是建立了一个 VMA(虚拟内存区域),并记录了对应的文件和偏移。
- 当进程访问这个区域时:
- 发生 缺页异常。
- 内核检查对应的文件页是否已经在 页缓存 里。
- 如果在,直接把这个 文件页缓存的物理页 映射到进程页表。
- 如果不在,就从磁盘读到页缓存,再建立页表映射。
- 因此,
mmap的用户地址空间和内核的文件页缓存是 同一块物理页(零拷贝)。
2. read / write 的情况
read(fd, buf, size):- 内核找到文件对应的页缓存。
- 如果页缓存没有数据,就先从磁盘读到页缓存。
- 然后内核会执行一次 copy_to_user:把页缓存的数据拷贝到用户进程的
buf。 - 所以这里有一次 内核态页缓存 → 用户缓冲区 的拷贝。
- 内核找到文件对应的页缓存。
write(fd, buf, size):- 内核先从用户态
buf执行 copy_from_user,拷贝数据到页缓存。 - 页缓存被标记为脏页,稍后由回写线程(writeback)写回磁盘。
- 这里也是一次 用户缓冲区 → 内核态页缓存 的拷贝。
- 内核先从用户态
3. 对比总结
| 操作 | 文件页缓存 | 用户空间 | 是否 copy |
|---|---|---|---|
mmap + 缺页访问 | 直接映射同一物理页 | 页表指向页缓存 | 无拷贝(零拷贝) |
read | 页缓存中取数据 | 复制到用户 buf | 有拷贝 |
write | 从用户 buf 拷贝到页缓存 | 页缓存标记脏页 | 有拷贝 |
关键点:
mmap可以做到 零拷贝,因为用户进程和内核共享同一份页缓存。read/write必然涉及到 数据在用户缓冲区和页缓存之间的复制。

1281

被折叠的 条评论
为什么被折叠?



