为什么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 

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

 echo 20 > /proc/sys/vm/nr_hugepages 

解决了这个问题。 在ubuntu 14.04上测试过。 检查为什么我也无法使用mmap映射内存 。

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

 // 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); } 

内核的Documentation / vm / hugetlspage.txt提到大页面是 – 或者可能是有限的(例如,如果你将hugepages=N传递给内核,或者如果你通过/proc//sys/做事,或者如果这是没有在内核中配置等…)。 所以你不确定能得到它们。 使用大页面进行仅4K字节的小映射是一个错误(或者可能是失败)。 只有当要求许多兆字节(例如一千兆字节或更多)并且总是优化时(例如,您希望您的应用程序能够在没有它们的情况下运行的内核上),大页面是值得的。

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

 echo 1 > /proc/sys/vm/overcommit_memory