Я хочу створити програму, яка буде імітувати ситуацію поза пам'яттю (OOM) на сервері Unix. Я створив цей надпростий пожирач пам'яті:
#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;
}
Він їсть стільки пам'яті, скільки визначено, в memory_to_eat
якій зараз рівно 50 ГБ оперативної пам’яті. Він виділяє пам'ять на 1 Мб і друкує саме ту точку, де вона не може виділити більше, так що я знаю, яке максимальне значення йому вдалося з'їсти.
Проблема в тому, що вона працює. Навіть у системі з 1 Гб фізичної пам'яті.
Коли я перевіряю зверху, я бачу, що процес з’їдає 50 ГБ віртуальної пам’яті і лише менше 1 Мб пам'яті резидента. Чи існує спосіб створити пам'ять, яка дійсно споживає його?
Характеристики системи: Ядро Linux 3.16 ( Debian ), швидше за все, з увімкненою надмірною передачею (не впевнений, як це перевірити) без заміни та віртуалізації.
sysctl -w vm.overcommit_memory=2
як root; див. mjmwired.net/kernel/Documentation/vm/overcommit-accounting . Зауважте, що це може мати інші наслідки; зокрема, дуже великі програми (наприклад, ваш веб-браузер) можуть нерезулювати помічники програм (наприклад, зчитувач PDF).