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

时间:2015-05-07 02:04:06

标签: c linux memory memory-management

据我所知,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(尽可能少的延迟)。它一开始是mmap 1GB内存的可行解决方案吗?据推测,虽然只使用了10MB,但剩余的990MB可供其他应用程序使用。当罕见的情况发生时需要1GB时,我认为延迟比使用malloc或realloc要少得多。

当不再需要额外的990MB时,它是一个可行的解决方案,可以重新映射到10MB然后再回到1GB,以便释放不再需要的990MB,但仍然可以立即访问它?我认为这比重新分配操作快得多?

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

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

2 个答案:

答案 0 :(得分:2)

对于运行Linux的大多数处理器来说,你是对的。一千兆字节的mmap空间只占用几KB。它超过了你的16kb,因为必须分配“页表”以跟踪你已分配的内存地址,但不能

现代malloc通常会直接使用mmap进行大量分配,因此如果malloc占用大量空间,您将获得与直接使用mmap几乎相同的效果......可能(但不保证)。

您应该做的一件事是将MAP_NORESERVE添加到您的标志中(如果已定义)以确保该空间实际上未在某处分配。在Linux上,此标志通常几乎没有(或没有)效果,但对于最新内核的特定配置,mmap 在交换中分配,除非您提供此标志。

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

最后一件事,如果你mmap巨大的空间,Linux后来发现它超过订阅它将杀死进程。确保您有过多数量的交换空间。您可以通过在/ tmp(具有8GB RAM)上使用30GB tmpfs来证明这一点。

答案 1 :(得分:1)

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

在64位系统上,运行 out 的虚拟地址空间不是问题,但我怀疑在前期分配它仍然有好处。您可以查看madvise(MADV_HUGEPAGE)以保存页面表空间。

此外,您可以madvise(MADV_DONTNEED)代替mremap