Quero criar um programa que simule uma situação de falta de memória (OOM) em um servidor Unix. Eu criei este super comedor de memória super simples:
#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;
}
Ele consome tanta memória quanto definida, na memory_to_eat
qual agora são exatamente 50 GB de RAM. Ele aloca memória em 1 MB e imprime exatamente o ponto em que deixa de alocar mais, para que eu saiba qual valor máximo conseguiu consumir.
O problema é que funciona. Mesmo em um sistema com 1 GB de memória física.
Quando verifico na parte superior, vejo que o processo consome 50 GB de memória virtual e apenas menos de 1 MB de memória residente. Existe uma maneira de criar um comedor de memória que realmente o consome?
Especificações do sistema: Kernel do Linux 3.16 ( Debian ) provavelmente com a confirmação excessiva ativada (não sei como fazer check-out) sem troca e virtualizada.
sysctl -w vm.overcommit_memory=2
como root; consulte mjmwired.net/kernel/Documentation/vm/overcommit-accounting . Observe que isso pode ter outras consequências; em particular, programas muito grandes (por exemplo, seu navegador da web) podem não gerar programas auxiliares (por exemplo, o leitor de PDF).