代码之家  ›  专栏  ›  技术社区  ›  robottobor

内存映射文件的优点是什么?

  •  76
  • robottobor  · 技术社区  · 18 年前

    我特别关注以下几点,按重要性排序:

    • 并发性
    • 随机存取
    • 易用性
    • 便携性
    4 回复  |  直到 18 年前
        1
  •  58
  •   MarkR    18 年前

    我认为这样做的好处是,与传统的读取文件方法相比,可以减少所需的数据复制量。

    如果数据实际上必须从光盘中读取(如在物理I/O中),那么操作系统仍然必须将其读入,页面错误可能不会比系统调用的性能更好,但是如果它们没有读取(即已经在操作系统缓存中),理论上性能应该更好。

    另一方面,内存映射文件没有异步接口——如果您试图访问未映射到的页面,它会生成一个页面错误,然后使线程等待I/O。


    内存映射文件的明显缺点是在32位操作系统上—您很容易耗尽地址空间。

        2
  •  51
  •   Scott Stanchfield    18 年前

    我使用了一个内存映射文件来实现用户键入时的“自动完成”功能。我在一个索引文件中存储了超过100万个产品零件号。该文件具有一些典型的头信息,但文件的大部分是按键字段排序的固定大小记录的巨大数组。

    在运行时,该文件是内存映射的,转换为 C struct 数组,然后我们进行二进制搜索,根据用户类型查找匹配的零件号。实际上,从磁盘上只读取了文件中的几个内存页——在二进制搜索过程中命中的任何一页。

    • 并发性——我遇到了一个实现问题,它有时会在同一个进程空间中多次映射文件的内存。我记得这是一个问题,因为有时系统找不到足够大的可用虚拟内存块来映射文件。解决方案是只映射一次文件,然后关闭对它的所有调用。回想起来,使用成熟的Windows服务当然很酷。
        3
  •  22
  •   bog    18 年前

    内存映射文件可用于替换读/写访问,或支持并发共享。当你将它们用于一种机制时,你也会得到另一种机制。

    与在文件中查找、写入和读取不同,您可以将文件映射到内存中,只需访问您期望的位。

    休息

    当考虑多进程通过映射内存使用相同的“文件”的可能性时,会出现并发。在读/写模型中,如果两个进程向文件的同一区域写入数据,您可以非常确定该进程的一个数据将到达该文件,从而覆盖另一个进程的数据。你会得到一个,或者另一个,但不是一些奇怪的混合。我必须承认,我不确定这是否是任何标准强制要求的行为,但这是你可以非常依赖的。(这实际上是一个很好的后续问题!)

    然而 ,如果我使用内存映射文件方法,进程1将执行一个4字节的内存存储,然后是另一个4字节的内存存储(假设这不是最大内存存储大小)。过程2将做同样的事情。根据进程运行的时间,您可能会看到以下任何情况:

    11111111
    22222222
    11112222
    22221111
    

    解决这个问题的办法是使用显式互斥——这在任何情况下都可能是个好主意。无论如何,在读/写文件I/O的情况下,您有点依赖O/S来做“正确的事情”。

    使用映射文件进行编辑:当您使用映射文件时,会有一种诱惑,即在文件本身中嵌入指向文件中数据的指针(想想存储在映射文件中的链表)。您不希望这样做,因为文件可能在不同的时间或在不同的进程中映射到不同的绝对地址。而是在映射文件中使用偏移。

        4
  •  1
  •   Paul Nathan    18 年前

    随机访问更容易 易用性。没有那么好。 便携性-不那么热。