我想创建一个程序来模拟Unix服务器上的内存不足(OOM)情况。我创建了这个超级简单的内存消耗者:
#include <stdio.h>
#include <stdlib.h>
unsigned long long memory_to_eat = 1024 * 50000;
size_t eaten_memory = 0;
void *memory = NULL;
int eat_kilobyte()
{
memory = realloc(memory, (eaten_memory * 1024) + 1024);
if (memory == NULL)
{
// realloc failed here - we probably can't allocate more memory for whatever reason
return 1;
}
else
{
eaten_memory++;
return 0;
}
}
int main(int argc, char **argv)
{
printf("I will try to eat %i kb of ram\n", memory_to_eat);
int megabyte = 0;
while (memory_to_eat > 0)
{
memory_to_eat--;
if (eat_kilobyte())
{
printf("Failed to allocate more memory! Stucked at %i kb :(\n", eaten_memory);
return 200;
}
if (megabyte++ >= 1024)
{
printf("Eaten 1 MB of ram\n");
megabyte = 0;
}
}
printf("Successfully eaten requested memory!\n");
free(memory);
return 0;
}
它消耗的内存与定义的内存一样多memory_to_eat
,现在恰好是50 GB的RAM。它按1 MB分配内存,并精确打印无法分配更多内存的点,这样我就知道它设法吃掉了哪个最大值。
问题是它有效。即使在具有1 GB物理内存的系统上。
当我检查顶部时,我看到该进程占用了50 GB的虚拟内存,而占用的驻留内存不到1 MB。有没有办法创建确实消耗掉它的内存消耗者?
系统规范:Linux内核3.16(Debian)最有可能启用了过量使用(不确定如何检出),并且没有交换和虚拟化。
sysctl -w vm.overcommit_memory=2
以root身份运行,则原始程序将按预期运行;请参阅mjmwired.net/kernel/Documentation/vm/overcommit-accounting。请注意,这可能会带来其他后果;特别是非常大的程序(例如您的Web浏览器)可能无法生成辅助程序(例如PDF阅读器)。