Je veux créer un programme qui simulera une situation de manque de mémoire (MOO) sur un serveur Unix. J'ai créé ce mangeur de mémoire super 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;
}
Il consomme autant de mémoire que défini dans memory_to_eat
lequel se trouve maintenant exactement 50 Go de RAM. Il alloue de la mémoire de 1 Mo et imprime exactement le point où il ne parvient pas à en allouer davantage, de sorte que je sache quelle valeur maximale il a réussi à manger.
Le problème est que cela fonctionne. Même sur un système avec 1 Go de mémoire physique.
Lorsque je vérifie haut, je vois que le processus consomme 50 Go de mémoire virtuelle et seulement moins de 1 Mo de mémoire résidente. Existe-t-il un moyen de créer un mangeur de mémoire qui le consomme vraiment?
Spécifications du système: noyau Linux 3.16 ( Debian ) très probablement avec overcommit activé (je ne sais pas comment le vérifier) sans swap et virtualisé.
sysctl -w vm.overcommit_memory=2
tant que root; voir mjmwired.net/kernel/Documentation/vm/overcommit-accounting . Notez que cela peut avoir d'autres conséquences; en particulier, des programmes très volumineux (par exemple votre navigateur Web) peuvent ne pas générer de programmes d'aide (par exemple le lecteur PDF).