我制作的游戏将世界划分为描述世界的数据块。我将块保存在动态分配的数组中,因此在初始化世界数据结构时我必须使用malloc()
。
阅读malloc()
man page,附注如下:
默认情况下,Linux遵循乐观的内存分配策略。 这意味着当
malloc()
返回非NULL时,无法保证 内存确实可用。如果事实证明了 系统内存不足,一个或多个进程将被杀死 OOM杀手。有关更多信息,请参阅的说明 {em}中的 / proc / sys / vm / overcommit_memory 和 / proc / sys / vm / oom_adj 以及Linux内核源文件 文档/ VM /过量使用计费
如果Linux设置为使用乐观内存分配,那么这是否意味着它始终不会返回我在调用proc(5)
时请求的全部内存量?
我读到通过修改内核可以禁用乐观的内存分配,但我不想这样做。
那么有没有办法检查程序是否已分配所请求的金额?
答案 0 :(得分:6)
从应用程序的角度来看,这不是您需要处理的事情。不希望随机进程被" OOM杀手"杀死的用户将通过
禁用过度使用echo "2" > /proc/sys/vm/overcommit_memory
这是他们的选择,而不是你的选择。
但从另一个角度来看,这并不重要。典型"推荐"交换量是如此荒谬,以至于没有合理数量的malloc
将无法拥有物理存储来支持它。但是,您可以轻松分配这么多(即使使用强制MAP_POPULATE
或手动触摸它),以使系统保持交换数小时/天/周。没有规范的方法可以让系统通知您,如果您想要的内存量会使系统交换陷入困境,则会出错。
整个情况很糟糕,但作为应用程序开发人员,您在修复程序中的角色只是正确使用malloc
并检查null返回值。其余的责任在于发行版和内核维护者。
答案 1 :(得分:1)
而不是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
开始映射到内存中;对内存的所有更改也会透明地写入文件 - 如果有足够的RAM,则无需担心,因为linux会自动映射页面进出。
请注意,除非您定义了某个功能测试宏,否则未定义其中一些标志:
某些标志常量仅在
_BSD_SOURCE
或_SVID_SOURCE
时定义_GNU_SOURCE
已定义。 (要求MAP_32BIT
也足够了,并且要求宏具体更合乎逻辑,因为 这些标志都是特定于Linux的。)相关的标志是:MAP_ANONYMOUS
,MAP_ANON
(以及同义词MAP_DENYWRITE
),MAP_EXECUTABLE
,MAP_FILE
,MAP_GROWSDOWN
,MAP_HUGETLB
,MAP_LOCKED
,MAP_NONBLOCK
,MAP_NORESERVE
,MAP_POPULATE
,MAP_STACK
和{{1}}。