【问题标题】:Why does dereferencing pointer from mmap cause memory usage reported by top to increase?为什么从 mmap 取消引用指针会导致 top 报告的内存使用量增加?
【发布时间】:2017-09-14 00:03:16
【问题描述】:

我使用 MAP_SHARED 和 PROT_READ 调用 mmap() 来访问大小约为 25 GB 的文件。我注意到推进返回的指针对应用程序顶部的 %MEM 没有影响,但是一旦我开始在不同位置取消引用指针,内存就会急剧增加并上限为 55%。调用 munmap 后,该值会回落至 0.2%。

我不知道我是否应该相信那些价值 55% 的顶级报告。看起来它实际上并没有使用可用的 16 GB 中的 8 GB。我应该担心吗?

【问题讨论】:

  • 系统在内存使用之前不会真正分配内存。这就是为什么通过使用它,你会导致它被保留。
  • 据我了解,我应该只使用没有分配页面的虚拟地址空间。这让我想知道,一旦指针被取消引用,我的应用程序是否报告它正在使用一组虚拟地址,但实际上并没有使用物理内存。这样一来,top 报告的 55% 就没什么意义了。
  • %MEM 显示驻留集。也就是说,程序当前使用了多少实际内存。但这只是故事的一部分:如果该内存是共享的,它将显示为所有共享它的进程的驻留。另一方面,在文件映射的情况下,系统可能会在需要时随时恢复该内存,尽管您的程序正在使用它,但它不会阻止其他程序使用它。
  • 看来你是对的。我使用了另一个实用程序,它可以帮助我查看内存中可回收的内容和不可回收的内容。在这种情况下,它主要是可回收的。如果你把它作为答案,我会把它标记为正确的。

标签: linux mmap


【解决方案1】:

当您第一次映射文件时,它所做的只是保留地址空间,如果您不通过MAP_POPULATE,它不一定会从文件中读取任何内容(操作系统可能会进行一些预取,不需要,并且通常在您开始阅读/写作之前不会)。

当您第一次从给定的内存页面读取时,会触发page fault。大多数人在听到这个名字时会想到这个“无效页面错误”,它是:

  1. 小故障 - 数据已加载到内核中,但需要建立该地址到加载数据的用户空间映射(快速)
  2. 重大故障 - 数据根本没有加载,内核需要为数据分配一个页面,从磁盘填充它(慢),然后执行与次要故障情况相同的用户空间映射

您看到的行为可能是由于映射文件太大而无法与其他所有想要保持常驻的文件一起放入内存中,因此:

  1. 当第一次映射时,初始页还没有映射到进程(其中一些可能在内核缓存中,但它们不计入进程,除非它们通过次要链接到进程的地址空间页面错误)
  2. 您从文件中读取,导致次要和主要错误,直到您填满主 RAM
  3. 一旦填满主 RAM,新页面中的错误通常会导致旧页面之一被丢弃(您使用所有页面的次数不如操作系统和其他进程使用它们的页面多,因此低活动页面,尤其是那些可以免费删除而不是写入页面/交换文件的页面,是理想的丢弃页面),因此您的内存使用量稳定(对于读取的每个页面,您都会删除另一个页面)
  4. 当您munmap 时,针对您的进程的记帐将被删除。许多页面可能仍在内核缓存中,但除非它们很快被重新映射并再次访问,否则它们很可能首先在切块上被丢弃,如果有其他东西请求内存

正如评论者所说,共享内存映射文件记帐变得奇怪;每个进程都为内存“收费”,但即使没有其他进程映射它,它们也会将其报告为共享,因此区分“共享”是不切实际的,因为它是MAP_SHARED 并由内核缓存支持,但没有其他人它是否已映射,因此它实际上由该进程唯一拥有”来自“共享,因为 N 个进程正在映射相同的数据,累积报告 shared_amount * N 使用情况,但实际上只消耗 shared_amount 内存总量(加上一个微不足道的数量来维护每个处理每个映射的页表)。如果计数不对齐,则无需担心。

【讨论】:

  • 感谢您的解释。这与我注意到的非常吻合。我唯一不清楚的是你所说的“主RAM”是什么意思。您是在区分物理 RAM 与交换还是引用其他限制?
  • @Tails86:是的,我指的是实际的物理 RAM,而不是交换。操作系统喜欢将所有正在使用的东西都保存在物理 RAM 中,但显然不能总是这样做,因此映射为共享且未被弄脏的文件支持的内存可以在压力下被丢弃(如果它是脏的就写入,如果它被访问则重新加载再次),并且可以将其他内存写入页面/交换文件(并按需重新读取)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-21
  • 2010-10-25
相关资源
最近更新 更多