我正在制作一个游戏,将世界划分为描述世界的大量数据。 我把块保存在一个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_32BIT
,MAP_ANONYMOUS
(和同义词MAP_ANON
),MAP_DENYWRITE
,MAP_EXECUTABLE
,MAP_FILE
,MAP_GROWSDOWN
,MAP_HUGETLB
,MAP_LOCKED
,MAP_NONBLOCK
,MAP_NORESERVE
,MAP_POPULATE
和MAP_STACK
。