在Linux中的malloc() – “不能保证内存真的可用”?

我正在制作一个游戏,将世界划分为描述世界的大量数据。 我把块保存在一个dynamic分配的数组中,所以当初始化世界的数据结构时,我必须使用malloc()

读取malloc()手册页 ,有一个注释如下:

默认情况下,Linux遵循乐观的内存分配策略。 这意味着当malloc()返回非NULL时,不能保证内存真的可用。 如果事实certificate系统内存不足,OOM杀手会杀死一个或多个进程。 有关更多信息,请参阅proc(5) / proc / sys / vm / overcommit_memory/ proc / sys / vm / oom_adj以及Linux内核源文件Documentation / vm / overcommit-accounting

如果Linux设置为使用乐观的内存分配,那么这是否意味着它并不总是返回我在malloc()调用中请求的全部内存量?

我读了乐观的内存分配,通过修改内核被禁用,但我不想这样做。

那么有没有办法来检查程序是否已经分配了请求的数量?

从应用程序的角度来看,这不是你需要处理的事情。 不希望被“OOM杀手”杀死的随机进程的用户将禁用自己的overcommit

 echo "2" > /proc/sys/vm/overcommit_memory 

这是他们的选择,不是你的选择。

但从另一个角度来看,这并不重要。 典型的“推荐”数量的交换是如此荒谬,以至于没有合理数量的malloc将不能有物理存储来支持它。 但是,您可以轻松地分配这么多(即使强制使用MAP_POPULATE或手动触摸全部),以使系统在几个小时/天/周内交换。 有没有规范的方式要求系统通知你,并给出一个错误,如果你想要的内存量将陷入系统交换。

整个情况是一团糟,但作为应用程序开发人员,您在修复中的角色是正确使用malloc并检查返回值为空。 其余的职责是发行版和内核维护者。

而不是malloc你可以直接用mmap分配必要的内存, MAP_POPULATE建议内核立即映射页面。

 #include <sys/mman.h> // allocate length bytes and prefault the memory so // that it surely is mapped void *block = mmap(NULL, length, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_POPULATE, -1, 0); // free the block allocated previously // note, you need to know the size munmap(block, length); 

但更好的选择是通常世界被保存到一个文件,所以你可以直接从一个文件mmap的内容:

 int fd = open('world.bin', 'r+'); void *block = mmap(NULL, <filesize>, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); 

文件world.bin从地址block开始映射到内存中; 对内存的所有更改也会透明地写入文件 – 无需担心内存是否足够,因为Linux会自动将内存映射到内存中。


请注意,除非您定义了某个特征测试宏,否则这些标志中的一些标志不会被定义:

某些标志常量只有在定义了_BSD_SOURCE_SVID_SOURCE被定义。 (需要_GNU_SOURCE也足够了,因为这些标志都是特定于Linux的,所以要求这个宏具有逻辑性)。相关标志有: MAP_32BITMAP_ANONYMOUS (和同义词MAP_ANON ), MAP_DENYWRITEMAP_EXECUTABLEMAP_FILEMAP_GROWSDOWNMAP_HUGETLBMAP_LOCKEDMAP_NONBLOCKMAP_NORESERVEMAP_POPULATEMAP_STACK