mmap 请求的内存大小对可用内存有什么影响?

What affect on available free memory does the size of memory requested by mmap have?

我了解 mmap 请求的内存在读取或写入之前不会实际使用。所以在下面的测试用例中:

int main()
  {
  char *A=mmap(NULL,1073741824/4, PROT_WRITE|PROT_READ,MAP_PRIVATE|MAP_ANONYMOUS,-1,0); 
  *A='a';
  char *B=mmap(NULL,1073741824/4, PROT_WRITE|PROT_READ,MAP_PRIVATE|MAP_ANONYMOUS,-1,0);
  *B='b';
  char *C=mmap(NULL,1073741824/4, PROT_WRITE|PROT_READ,MAP_PRIVATE|MAP_ANONYMOUS,-1,0);
  *C='c';
  char *D=mmap(NULL,1073741824/4, PROT_WRITE|PROT_READ,MAP_PRIVATE|MAP_ANONYMOUS,-1,0);
  *D='d'
  char *E=mmap(NULL,1073741824/4, PROT_WRITE|PROT_READ,MAP_PRIVATE|MAP_ANONYMOUS,-1,0);
  }

我假设其他程序可用的内存只减少了 16k (4 x 4096),我是否正确?我没有看到使用 free() 时可用内存有任何更大的减少,所以我假设是这样。

既然如此,假设我有一个应用程序通常使用 10MB 的内存,但在极少数情况下可能突然需要高达 1GB(尽可能少的延迟)。一开始就映射 1GB 内存是可行的解决方案吗?据推测,虽然只使用了 10MB,但剩余的 990MB 可供其他应用程序使用。当极少数情况下需要 1GB 时,我认为延迟会比必须 malloc 或 realloc 少得多。

当不再需要额外的 990MB 时,重新映射到 10MB 然后再映射回 1GB 以释放不再立即需要的 990MB 是否是一个可行的解决方案,但仍然提供对它的即时访问下次?我假设这会比 realloc 操作快得多?

我这里的一些假设可能不正确。我试图更好地了解 mmap 如何影响可用内存,以及 mremap 与使用 malloc 和 realloc 的性能影响。

以上内容基于现代 linux 内核,使用 gcc,假设 4k 页面大小和超出此范围的可移植性,不是重要的优先事项。

对于大多数处理器,当 运行 Linux 你是对的。 mmap 一千兆字节的 space 将只占用几 KB。它超过了您的 16kb,因为必须分配 "page tables" 来跟踪您分配的内存地址,但不会

现代 malloc 通常会几乎直接使用 mmap 进行大分配,所以如果你 malloc 一个巨大的 space 你会得到与使用几乎相同的效果mmap 直接...可能(但不保证)。

您可能应该做的一件事是将 MAP_NORESERVE 添加到您的标志(如果已定义)以确保 space 实际上没有分配到某处。在 Linux 上,此标志 通常 几乎没有(或没有)影响,但对于最近内核的特定配置 mmap 除非你给出这个标志,否则将在交换中分配。

但是请注意,某些 Unix(以及我认为 Linux 下的某些处理器类型)您将无法分配尽可能多的地址 space。如果 mmap 被拒绝,您应该准备好使用较小的映射重试。

最后一件事,如果您 mmap 巨大的 space 并且 Linux 后来发现它的订阅过多,它将终止进程。确保您有 过多的 交换量 space。您可以通过在 /tmp 上有一个 30GB 的 tmpfs 来证明它的合理性(具有 8GB 的​​ RAM)。

可能值得进行大量的前期分配,不是因为您的程序使用了物理内存,而是因为虚拟[=22] =]记忆。在 32 位系统上,如果您有碎片堆,很可能不会进行任何可能的 1G 分配。但是如果你先分配它,较小的片段更有可能正确地安排自己。

在64位系统上,运行 out of virtual address space 不是问题,但我怀疑分配它仍有优势前期。您可能会查看 madvise(MADV_HUGEPAGE) 以保存分页表 space。

此外,您可以 madvise(MADV_DONTNEED) 而不是 mremap