mmap
可用于在进程之间共享只读内存,从而减少内存占用量:
mmap
是一个文件,使用映射的内存 - >数据加载到RAM mmap
是一个文件,使用映射的内存 - >操作系统重新使用相同的内存但是这个怎么样:
mmap
是一个文件,将其加载到内存中,然后退出。 mmap
s 同一个文件,从P1的访问权限访问仍然很热的内存。是否从磁盘再次加载数据?即使“mmap count”暂时降为零,操作系统是否足够智能以重新使用虚拟内存?
不同操作系统之间的行为是否不同? (我最感兴趣的是Linux / OS X)
编辑:如果操作系统不够智能 - 如果有一个“后台进程”,保留文件mmap
,它会不会有帮助,所以它永远不会离开至少一个进程的地址空间?
当我mmap
和munmap
相同的文件连续快速地,可能(但不一定)在同一个过程中时,我当然对性能感兴趣。
EDIT2:我看到很长一段时间内完全无关紧要的答案。重申一点 - 我可以依赖Linux / OS X来重新加载已驻留在内存中的数据,而不是mmap
内存段中的先前页面命中,即使特定区域不再是{{ 1}}任何过程?
答案 0 :(得分:7)
内存中文件内容的存在与否与mmap
系统调用的关联程度远远低于您的想法。当您mmap
文件时,它不一定会将其加载到内存中。当你munmap
(或者进程退出)时,它不一定会丢弃页面。
有许多不同的东西可以触发文件的内容加载到内存中:映射,正常读取,执行它,尝试访问映射到文件的内存。类似地,有不同的东西可能导致文件的内容从内存中删除,主要与操作系统决定它想要内存更重要的东西有关。
在您提问的两个场景中,请考虑在步骤1和步骤2之间插入一个步骤:
mmap
ed文件从内存中逐出,以腾出空间。在这种情况下,如果文件的内容再次映射并在步骤2中再次使用,则可能必须重新加载到内存中。
与
mmap
ed文件的内容在内存中徘徊。在这种情况下,不需要在步骤2中重新加载文件的内容。
就文件内容的变化而言,两种情况没有太大区别。这就像第1.5步那样会产生更重要的差异。
对于不断访问文件的后台进程,以确保它保存在内存中(例如,通过扫描文件,然后在循环中休眠很短的时间),这当然会强制文件保留在内存中。但你可能最好只是让操作系统决定何时驱逐文件以及什么时候不驱逐它。
答案 1 :(得分:3)
第二个进程可能会在缓冲区缓存中找到第一个进程的数据。因此,在大多数情况下,数据不会再从磁盘加载。但由于缓冲区缓存是一个缓存,因此无法保证页面之间不会被逐出。
您可以启动第三个进程并使用mmap(2)和mlock(2)来修复ram中的页面。但这可能会造成比它值得更多的麻烦。
Linux将UNIX缓冲区缓存替换为page cache。但原则仍然是一样的。 Mac OS X等效项称为Unified Buffer Cache (UBC)。