内存子系统本身对“文件”这个操作系统概念没有任何理解,并且已经出现了一些操作系统根本不使用文件。您对工作原理的理解很接近,但有点偏离mmap
。
每个进程都有自己的虚拟地址空间,这可能与物理内存几乎没有关系(很多虚拟地址空间根本没有任何关联的内存,永远,换出的虚拟内存没有任何物理内存)。系统使用某种查找表(在 x86 上称为描述符表)来指定哪些虚拟地址范围映射到哪些物理地址范围。非“驻留”的虚拟内存(已换出、mmap
ped 但未加载)有一个“不存在”条目。
每当程序尝试访问此内存时,CPU 都会导致页面错误,这会告诉操作系统在某处找到适当的内容并将它们加载到物理内存中。在交换的情况下,内容是从交换文件或分区中加载出来的;在 的情况下mmap
,它们是从文件系统的某个地方加载出来的。
将它们放入物理内存和更新描述符表的机制可能会有所不同。您所描述的是 DMA,它允许驱动控制器将内容直接复制到一块物理内存中,以及零复制 I/O,这是一种技术,操作系统只是创建一个新的描述符映射,告诉处理器“传送" 物理内存区域进入程序的地址空间。技术上都不需要mmap
(操作系统可以“手动”加载文件并将其复制到程序的新缓冲区中,这可能发生在读取-复制-更新情况下),但现代系统会像您描述的那样做。
物理内存不一定是连续的。当mmap
调用 POSIX 版本时,操作系统会length
为映射分配字节,但由于有了虚拟内存,这些字节可以分成多个块并由处理器映射在一起。
如果多个进程试图访问mmap
同一个文件,操作系统的行为取决于访问是只读的还是读/写的;只读副本可以在许多进程之间共享(例如实际的可执行代码;这就是为什么即使 Chrome 可能有几十个进程在运行,Chrome 二进制文件只在内存中一次)。