Tôi muốn tạo một chương trình mô phỏng tình huống hết bộ nhớ (OOM) trên máy chủ Unix. Tôi đã tạo ra bộ nhớ siêu đơn giản này:
#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;
}
Nó ăn nhiều bộ nhớ như được xác định trong memory_to_eat
đó bây giờ chính xác là 50 GB RAM. Nó phân bổ bộ nhớ cho 1 MB và in chính xác điểm không thể phân bổ nhiều hơn, để tôi biết giá trị tối đa mà nó quản lý để ăn.
Vấn đề là nó hoạt động. Ngay cả trên một hệ thống có 1 GB bộ nhớ vật lý.
Khi tôi kiểm tra hàng đầu, tôi thấy rằng quá trình này chiếm 50 GB bộ nhớ ảo và chỉ dưới 1 MB bộ nhớ lưu trú. Có cách nào để tạo ra một bộ nhớ ăn mà thực sự tiêu thụ nó?
Thông số kỹ thuật hệ thống: Linux kernel 3.16 ( Debian ) rất có thể được kích hoạt vượt mức (không chắc chắn cách kiểm tra) mà không có trao đổi và ảo hóa.
sysctl -w vm.overcommit_memory=2
root; xem mjmwired.net/kernel/Documentation/vm/overcommit-accounting . Lưu ý rằng điều này có thể có hậu quả khác; đặc biệt, các chương trình rất lớn (ví dụ: trình duyệt web của bạn) có thể không sinh ra các chương trình trợ giúp (ví dụ: trình đọc PDF).