Quiero crear un programa que simule una situación de falta de memoria (OOM) en un servidor Unix. Creé este comedor de memoria súper simple:
#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;
}
Come tanta memoria como se define en la memory_to_eat
que ahora es exactamente 50 GB de RAM. Asigna memoria en 1 MB e imprime exactamente el punto donde no puede asignar más, de modo que sé qué valor máximo logró comer.
El problema es que funciona. Incluso en un sistema con 1 GB de memoria física.
Cuando reviso la parte superior, veo que el proceso consume 50 GB de memoria virtual y solo menos de 1 MB de memoria residente. ¿Hay alguna manera de crear un comedor de memoria que realmente lo consuma?
Especificaciones del sistema: el kernel 3.16 de Linux ( Debian ) probablemente con un exceso de compromiso habilitado (no estoy seguro de cómo verificarlo) sin intercambio y virtualizado.
sysctl -w vm.overcommit_memory=2
como root; ver mjmwired.net/kernel/Documentation/vm/overcommit-accounting . Tenga en cuenta que esto puede tener otras consecuencias; en particular, los programas muy grandes (por ejemplo, su navegador web) pueden no generar programas auxiliares (por ejemplo, el lector de PDF).