Hul*_*000 5 c linux memory-management
我正在制作一个游戏,将世界划分为描述世界的数据块.我将块保存在动态分配的数组中,因此我必须malloc()在初始化世界的数据结构时使用.
阅读malloc()手册页,有一个注释如下:
默认情况下,Linux遵循乐观的内存分配策略.这意味着当
malloc()返回非NULL时,无法保证内存确实可用.如果事实证明系统内存不足,那么一个或多个进程将被OOM杀手杀死.欲了解更多信息,请参阅的说明 的/ proc/sys目录/ VM/overcommit_memory和的/ proc/sys目录/ VM/oom_adj中proc(5),和Linux内核源文件 文档/ VM /过载会计.
如果Linux设置为使用乐观内存分配,那么这是否意味着它并不总是返回我在调用中请求的全部内存量malloc()?
我读到通过修改内核来禁用乐观内存分配,但我不想这样做.
那么有没有办法检查程序是否已分配所请求的金额?
从应用程序的角度来看,这不是您需要处理的事情.不希望被"OOM杀手"杀死的随机进程的用户将通过自身禁用过度使用
echo "2" > /proc/sys/vm/overcommit_memory
Run Code Online (Sandbox Code Playgroud)
这是他们的选择,而不是你的选择.
但从另一个角度来看,这并不重要.典型的"推荐"交换量是如此荒谬,以至于没有合理数量的malloc物理存储无法支持它.但是,您可以轻松分配这么多(即使强制MAP_POPULATE或手动触摸它),以保持系统颠簸交换数小时/天/周.没有规范的方法要求系统通知您,如果您想要的内存量将使系统交换陷入困境,则会出错.
整个情况一团糟,但作为应用程序开发人员,您在修复中的角色只是malloc正确使用并检查null返回值.其余的责任在于发行版和内核维护者.
您可以直接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);
Run Code Online (Sandbox Code Playgroud)
但更好的选择是,通常世界会保存到文件中,因此您可以mmap直接从文件中获取内容:
int fd = open('world.bin', 'r+');
void *block = mmap(NULL, <filesize>, PROT_READ|PROT_WRITE,
MAP_SHARED, fd, 0);
Run Code Online (Sandbox Code Playgroud)
文件world.bin被映射到从地址开始的内存中block;对内存的所有更改也会透明地写入文件 - 无需担心是否有足够的 RAM,因为 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。