内存映射文件完全攻略(原理和性能)

  • 内容
  • 评论
  • 相关

假设采用标准系统调用 open()、read() 和 write() 来顺序读取磁盘文件,每个文件访问都需要系统调用和磁盘访问。又或者采用虚拟内存技术,以将文件 I/O 作为常规内存访问,这种方法称为内存映射文件,允许一部分虚拟内存与文件进行逻辑关联,这会导致显著的性能提高。

基本机制

实现文件的内存映射是将每个磁盘块映射到一个或多个内存页面。

最初,文件访问按普通请求调页来进行,从而产生缺页错误。这样,文件的页面大小部分从文件系统读取到物理页面(有些系统可以选择一次读取多个页面大小的数据块)。以后,文件的读写就按常规内存访问来处理。通过内存的文件操作,没有采用系统调用 read() 和 write() 的开销,而且简化了文件的访问和使用。

请注意,内存映射文件的写入不一定是对磁盘文件的即时(同步)写入。有的操作系统定期检查文件的内存映射页面是否已被修改,以便选择是否更新到物理文件。当关闭文件时,所有内存映射的数据会写到磁盘,并从进程虚拟内存中删除。

有些操作系统仅通过特定的系统调用来提供内存映射,而通过标准的系统调用来处理所有其他文件 I/O。然而,有的系统不管文件是否指定为内存映射,都选择对文件进行内存映射。

以 Solaris 为例,如果一个文件指定为内存映射(采用系统调用 mmaP()),那么 Solaris 会将该文件映射到进程地址空间。如果一个文件通过普通系统调用,如 open()、read() 和 write() 来打开和访问,那么 Solaris 仍然采用内存映射文件。然而,这个文件是映射到内核地址空间,无论文件如何打开,Solaris 都将所有文件 I/O 视为内存映射的,以允许文件访问在高效的内存子系统中进行。

多个进程可以允许并发地内存映射同一文件,以便允许数据共享。任何一个进程的写入会修改虚拟内存的数据,并且其他映射同一文件部分的进程都可看到。

根据虚拟内存的相关知识,可以清楚地看到内存映射部分的共享是如何实现的:每个共享进程的虚拟内存映射指向物理内存的同一页面,而该页面有磁盘块的复制,这种内存共享如图 1 所示。


内存映射文件
图 1 内存映射文件

本文标题:内存映射文件完全攻略(原理和性能)

本文地址:http://www.hosteonscn.com/3638.html

评论

0条评论

发表评论

邮箱地址不会被公开。 必填项已用*标注