Ich möchte ein Programm erstellen, das eine OOM-Situation (Out-of-Memory) auf einem Unix-Server simuliert. Ich habe diesen supereinfachen Speicherfresser erstellt:
#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;
}
Es verbraucht so viel Speicher wie definiert, in memory_to_eat
dem jetzt genau 50 GB RAM vorhanden sind. Es ordnet Speicher um 1 MB zu und druckt genau den Punkt, an dem es nicht mehr zuordnen kann, so dass ich weiß, welchen Maximalwert es geschafft hat, zu essen.
Das Problem ist, dass es funktioniert. Auch auf einem System mit 1 GB physischem Speicher.
Wenn ich oben nachschaue, sehe ich, dass der Prozess 50 GB virtuellen Speicher und nur weniger als 1 MB residenten Speicher verbraucht. Gibt es eine Möglichkeit, einen Speicherfresser zu erstellen, der ihn wirklich verbraucht?
Systemspezifikationen: Linux-Kernel 3.16 ( Debian ) höchstwahrscheinlich mit aktiviertem Overcommit (nicht sicher, wie man es auscheckt) ohne Swap und virtualisiert.
sysctl -w vm.overcommit_memory=2
als Root arbeiten. Siehe mjmwired.net/kernel/Documentation/vm/overcommit-accounting . Beachten Sie, dass dies andere Konsequenzen haben kann. Insbesondere sehr große Programme (z. B. Ihr Webbrowser) können möglicherweise keine Hilfsprogramme (z. B. den PDF-Reader) erzeugen.