【问题标题】:When and how is mmap'ed memory swapped in and out?mmap 的内存何时以及如何换入和换出?
【发布时间】:2017-09-18 09:07:30
【问题描述】:

据我了解,mmap 一个适合 RAM 的文件就像将文件放在内存中一样。

假设我们有 16G 的 RAM,我们首先映射一个 10G 的文件,我们会使用一段时间。这在访问方面应该是相当有效的。如果我们然后映射第二个 10G 文件,那会导致第一个被换出吗?还是其中的一部分?如果是这样,什么时候会发生?在 mmap 调用中,还是在访问新加载文件的内存区域时?

如果我们想再次访问第一个文件的指针的内存,这会使其再次加载交换文件吗?那么,假设我们在第一个文件和第二个文件对应的内存之间交替读取,这会导致灾难性的性能吗?

最后,如果其中任何一个属实,映射几个较小的文件会更好吗?

【问题讨论】:

    标签: linux mmap


    【解决方案1】:

    您的问题没有明确的答案,因为换入/换出由您的内核处理,并且每个内核都有不同的实现(Linux 本身根据您的使用情况、RT、桌面、服务器提供不同的配置文件……)

    不过,一般来说,无论您在内存中加载什么,都是使用页面完成的,因此内存中的 mmap 文件由所有内存级别(缓存、RAM 和交换)之间的页面加载(和卸载)。 然后,如果您将两个 10GB 数据加载到内存中,您将在 RAM 和您的 Swap 之间拥有部分数据,并且内核将尝试将您现在可能使用的页面保存在 RAM 中,并猜测您接下来将加载什么.

    这意味着,如果您对两个文件中的几个字节数据进行真正随机访问,您应该期待糟糕的性能,如果您从两个文件中依次访问连续块,您应该期待不错的表现。

    您可以阅读有关内核分页到虚拟内存理论的更多详细信息:

    【讨论】:

    • 我明白了。所以重要的是页面,而不是文件。从同一文件的不同页面访问内存应该具有与从不同文件访问不同页面相同的行为/性能吗?那么,将数据拆分成更小的文件没有意义吗?
    • 好吧,真正重要的是您的内核和交换策略(因为您无法控制分页的工作方式)。将数据拆分为多个较小的文件应该是一个计算好的交易。由于 I/O 阻塞,加载 10GB 文件将花费不可忽略的时间,导致其他服务在您访问它时停止(因为您将占用所有总线带宽或因为您可能从旧的旋转驱动器读取) .因此,将文件拆分为多个文件会降低数据加载速度,但有助于保持系统的响应速度更快。
    • I/O 不会阻塞其他进程。也就是说,拆分文件将无助于提高无关操作的性能。一般来说,如果数据被映射,即使在文件内,拆分也不会改善阻塞。
    【解决方案2】:

    如前所述,您的文件将分页访问;在 x86_64(和 IA32)架构上,一个页面通常是 4096 字节。因此,几乎没有任何文件将在 mmap 时加载。当您第一次访问任一文件中的某个页面时,内核将生成一个page fault 并加载您的一些文件。内核可能会预取页面,因此可能会加载多个页面。是否这样做取决于您的访问模式。

    一般来说,如果您的working set 适合内存,您的性能应该会很好。也就是说,如果您只是定期访问这两个文件的 3G 文件,只要您的进程有 3G 的 RAM 可用,那么事情通常应该没问题。

    在 64 位系统上,没有理由拆分文件,如果您需要的部分倾向于适合 RAM,那么您就可以了。

    请注意,如果您映射现有文件,则不需要交换空间来读取该文件。当一个对象由文件系统上的文件支持时,内核可以从该文件而不是交换空间中读取。但是,如果您在调用 mmap 时指定 MMAP_PRIVATE,则可能需要交换空间来保存更改的页面,直到您调用 msync。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-13
      • 1970-01-01
      • 2011-06-10
      • 2020-09-27
      • 2013-02-15
      • 1970-01-01
      相关资源
      最近更新 更多