mmap:映射文件会立即加载到内存中吗?

贸易方式

从手册中,我只知道mmap()将文件映射到虚拟地址空间,因此可以随机访问该文件。但是,我不清楚映射的文件是否立即加载到内存中?我猜想内核会按页面管理映射的内存,并且按需加载它们,如果我仅执行一些读取和写入操作,则只会加载几个页面。这是对的吗?

达蒙

不,是的,也许。这取决于。

mmap 通常调用仅意味着将映射文件的内容映射到其应用程序的地址空间,就像文件已加载到应用程序一样或者,就像文件确实存在于内存中一样,就好像它们是一个文件一样(包括将更改写回到磁盘上,假设您具有写访问权)。

不多不少。它没有加载任何东西的概念,应用程序也不知道这意味着什么。

尽管虚拟内存系统使应用程序看起来像这样,但是应用程序实际上并不了解诸如内存之类的任何东西。应用程序可以“查看”(和访问)的内存可能与实际的物理内存相对应,也可能不与实际的物理内存相对应,并且原则上可以随时更改,而无需事先警告,也没有明显的理由(对您的应用程序来说很明显)。
除了可能由于页面错误而导致一小段延迟之外,应用程序(原则上)完全不知道任何此类事件的发生,并且对此几乎没有控制权1

通常,由于遇到故障,应用程序将根据需要从映射文件(包括主可执行文件!)中加载页面。但是,操作系统通常会尝试推测性地预取数据以优化性能。

实际上,调用mmap将立即开始从映射的开始(异步地)预取页面,直到特定的实现指定大小。原则上,这意味着对于小文件,答案为“是”,而对于大文件,答案为“否”。
但是,mmap不会阻止等待预读完成,这意味着您不能保证mmap返回后立即任何文件放入RAM (无论如何,您始终不能保证!)。就此而言,答案是“也许”。

在Linux下,我上次查看时,默认的预取大小为31个块(约127k)-但这可能已更改,而且它是一个可调参数。当触摸预取区域附近或末尾的页面时,更多的页面将被异步预取。
如果你已经暗示MADV_RANDOMmadvise,预取是“不太可能发生”,在Linux下这完全禁用预取。

另一方面,给出MADV_SEQUENTIAL提示将从映射的开始开始异步“更积极地”预取(并且可能会更快地丢弃访问的页面)。在Linux下,“更积极”表示两倍于正常数量。

提供MADV_WILLNEED提示表明(但不保证)尽快加载给定范围内的所有页面(因为您要说的是访问它们)。操作系统可能会忽略这一点,但是在Linux下,它被视为命令而不是提示,最高为进程的最大RSS限制和实现指定的限制(如果我没记错的话,是物理RAM数量的1/2 )。
请注意,MADV_DONTNEED可以说在Linux下错误实现了该错误。提示不是用POSIX指定的方式解释的,即您可以暂时将页面分页出来,但是您的意思是丢弃它们对于只读映射的页面,这没有什么大的区别(除了很小的延迟(您说可以),但这确实很重要)对于其他一切。
特别是,在MADV_DONTNEEDLinux将操作系统懒惰地将它们写入磁盘后,使用Linux来释放不需要的页面的想法是行不通的您必须明确同步,否则请准备一个惊喜。

已经呼吁readahead呼吁之前文件描述符mmap(或者,有过读/写以前的文件),该文件的内容将在实践中确实是在RAM中立即。
但是,这仅是实现细节(统一的虚拟内存系统),并且受系统内存压力的影响。

调用will-mlock假设成功2-立即将请求的页面加载到RAM中。它会阻塞,直到所有页面都实际存在为止,并且您可以保证这些页面将保留在RAM中,直到您对其进行解锁为止。


1 有一些功能可以查询( mincore )当前是否确实存在特定范围内的任何页面或所有页面,并且可以在没有任何保证的情况下向OS暗示您 希望 看到的事件的功能( madvise ),最后强制将页面的有限子集显示在 mlock 特权进程的内存( )中的功能。

2可能不是因为缺乏特权,没有超出配额或存在的物理RAM数量。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

映射10 GB的文件并将其加载到内存中

来自分类Dev

使用mmap并将更改重新加载到文件中

来自分类Dev

SpriteKit:播放之前将声音文件预加载到内存中吗?

来自分类Dev

从XAML加载ResourceDictionary也将文件加载到内存中

来自分类Dev

合并大文件而不将整个文件加载到内存中?

来自分类Dev

C / C ++-使用mmap的内存映射文件

来自分类Dev

查找并追加到文件而不将其加载到内存中?

来自分类Dev

从Laravel存储下载而不将整个文件加载到内存中

来自分类Dev

如何在Perl中将文件加载到内存中

来自分类Dev

ZipArchive是否将整个zip文件加载到内存中

来自分类Dev

lxml的iterparse尝试将整个文件加载到内存中

来自分类Dev

如何将文件预加载到内存中?

来自分类Dev

.so文件是否整体加载到内存中?

来自分类Dev

如何在Perl中将文件加载到内存中

来自分类Dev

如何将大文件加载到内存中

来自分类Dev

写入NumPy内存映射仍会加载到RAM内存中

来自分类Dev

将大文件加载到内存中并使其在程序的所有运行时间中保持错误吗?

来自分类Dev

在 C 和 Python 中映射相同的文件,它真的会使用共享内存吗?mmap 可以跨不同的编程语言工作吗?

来自分类Dev

将numpy内存映射保存到新文件并从该文件加载新内存映射会导致值更改

来自分类Dev

将php文件加载到布局模板中吗?

来自分类Dev

将php文件加载到布局模板中吗?

来自分类Dev

快速映射和合并而不加载到内存

来自分类Dev

多少共享对象被加载到内存中

来自分类Dev

为什么mmap()(内存映射文件)比read()快

来自分类Dev

C#更改文件编码而不将所有文件加载到内存中

来自分类Dev

磁盘上的JSON文件加载到内存中的var中时,是否占用相同数量的空间?

来自分类Dev

在Rebol中,如何复制文件而不将其加载到内存中?

来自分类Dev

我如何读取文件,而不将其加载到内存中,例如D中的Delphi TFileStream类?

来自分类Dev

在不一次将整个文件立即加载到内存的情况下,读取大文件的最有效方法是什么?

Related 相关文章

  1. 1

    映射10 GB的文件并将其加载到内存中

  2. 2

    使用mmap并将更改重新加载到文件中

  3. 3

    SpriteKit:播放之前将声音文件预加载到内存中吗?

  4. 4

    从XAML加载ResourceDictionary也将文件加载到内存中

  5. 5

    合并大文件而不将整个文件加载到内存中?

  6. 6

    C / C ++-使用mmap的内存映射文件

  7. 7

    查找并追加到文件而不将其加载到内存中?

  8. 8

    从Laravel存储下载而不将整个文件加载到内存中

  9. 9

    如何在Perl中将文件加载到内存中

  10. 10

    ZipArchive是否将整个zip文件加载到内存中

  11. 11

    lxml的iterparse尝试将整个文件加载到内存中

  12. 12

    如何将文件预加载到内存中?

  13. 13

    .so文件是否整体加载到内存中?

  14. 14

    如何在Perl中将文件加载到内存中

  15. 15

    如何将大文件加载到内存中

  16. 16

    写入NumPy内存映射仍会加载到RAM内存中

  17. 17

    将大文件加载到内存中并使其在程序的所有运行时间中保持错误吗?

  18. 18

    在 C 和 Python 中映射相同的文件,它真的会使用共享内存吗?mmap 可以跨不同的编程语言工作吗?

  19. 19

    将numpy内存映射保存到新文件并从该文件加载新内存映射会导致值更改

  20. 20

    将php文件加载到布局模板中吗?

  21. 21

    将php文件加载到布局模板中吗?

  22. 22

    快速映射和合并而不加载到内存

  23. 23

    多少共享对象被加载到内存中

  24. 24

    为什么mmap()(内存映射文件)比read()快

  25. 25

    C#更改文件编码而不将所有文件加载到内存中

  26. 26

    磁盘上的JSON文件加载到内存中的var中时,是否占用相同数量的空间?

  27. 27

    在Rebol中,如何复制文件而不将其加载到内存中?

  28. 28

    我如何读取文件,而不将其加载到内存中,例如D中的Delphi TFileStream类?

  29. 29

    在不一次将整个文件立即加载到内存的情况下,读取大文件的最有效方法是什么?

热门标签

归档