为什么mmap无法分配内存?

时间:2014-12-24 08:51:20

标签: c mmap

我使用root权限运行该程序,但它一直在抱怨mmap无法分配内存。代码段如下:

#define PROTECTION (PROT_READ | PROT_WRITE)
#define LENGTH (4*1024)

#ifndef MAP_HUGETLB
#define MAP_HUGETLB 0x40000
#endif

#define ADDR (void *) (0x0UL)
#define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB)

int main (int argc, char *argv[]){
...
  // allocate a buffer with the same size as the LLC using huge pages
  buf = mmap(ADDR, LENGTH, PROTECTION, FLAGS, 0, 0);
  if (buf == MAP_FAILED) {
    perror("mmap");
    exit(1);
  }
...}

硬件:我有8G内存。处理器是ivybridge

Uname输出:

Linux mymachine 3.13.0-43-generic #72-Ubuntu SMP Mon Dec 8 19:35:06 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

编辑1:perror的输出

mmap: Cannot allocate memory

还添加了一行来打印errno

printf("something is wrong: %d\n", errno);

但输出是:

something is wrong: 12

编辑2:来自/ proc / meminfo的巨大的tlb相关信息

HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB

3 个答案:

答案 0 :(得分:16)

好吧,正如Documentation/vm/hugetlspage.txt建议的那样,

echo 20 > /proc/sys/vm/nr_hugepages

解决了这个问题。在ubuntu 14.04上测试过。同时检查Why I can't map memory with mmap

答案 1 :(得分:7)

当您使用MAP_HUGETLB时,mmap(2)调用可能会失败(例如,如果您的系统没有配置大页面,或者某些资源已耗尽),那么您几乎总是应该调用{{1}没有mmap作为故障恢复。此外,您不应该定义MAP_HUGETLB。如果未定义(由MAP_HUGETLB内部的系统头;根据体系结构或内核版本可能不同),请不要使用它!

<sys/mman.h>

内核的Documentation/vm/hugetlspage.txt提到大页面可能是有限的(例如,如果你将// allocate a buffer with the same size as the LLC using huge pages buf = mmap(NULL, LENGTH, PROTECTION, #ifdef MAP_HUGETLB MAP_HUGETLB | #endif MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); #ifdef MAP_HUGETLB if (buf == MAP_FAILED) { // try again without huge pages: buf = mmap(NULL, LENGTH, PROTECTION, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); }; #endif if (buf == MAP_FAILED) { perror("mmap"); exit(EXIT_FAILURE); } 传递给内核,或者你通过hugepages=N或{{1或者,如果没有在内核中配置,等等......)。所以你不确定能得到它们。使用大页面进行仅4K字节的小映射是一个错误(或者可能是失败)。只有在询问许多兆字节(例如1千兆字节或更多)并且始终是优化时(例如,您希望您的应用程序能够在没有它们的情况下在内核上运行),大页面是值得的。

答案 2 :(得分:0)

如果您肯定知道物理内存就足够了,那就是一个实用的解决方案:

echo 1 > /proc/sys/vm/overcommit_memory