Voglio creare un programma che simuli una situazione di memoria insufficiente (OOM) su un server Unix. Ho creato questo semplicissimo mangiatore di memoria:
#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;
}
Mangia tutta la memoria definita in memory_to_eat
cui ora sono esattamente 50 GB di RAM. Alloca memoria di 1 MB e stampa esattamente il punto in cui non riesce ad allocare di più, in modo che io sappia quale valore massimo è riuscito a mangiare.
Il problema è che funziona. Anche su un sistema con 1 GB di memoria fisica.
Quando controllo in alto vedo che il processo consuma 50 GB di memoria virtuale e solo meno di 1 MB di memoria residente. C'è un modo per creare un mangiatore di memoria che lo consumi davvero?
Specifiche di sistema: kernel Linux 3.16 ( Debian ) molto probabilmente con overcommit abilitato (non sono sicuro su come verificarlo) senza swap e virtualizzato.
sysctl -w vm.overcommit_memory=2
come root; vedi mjmwired.net/kernel/Documentation/vm/overcommit-accounting . Si noti che ciò può avere altre conseguenze; in particolare, programmi molto grandi (ad es. il tuo browser web) potrebbero non generare programmi di aiuto (ad es. il lettore PDF).