मैं एक प्रोग्राम बनाना चाहता हूं जो एक यूनिक्स सर्वर पर आउट-ऑफ-मेमोरी (ओओएम) स्थिति का अनुकरण करेगा। मैंने यह सुपर-सिंपल मेमोरी ईटर बनाया:
#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 एमबी से कम निवासी मेमोरी है। क्या मेमोरी भक्षक बनाने का एक तरीका है जो वास्तव में इसका उपभोग करता है?
सिस्टम स्पेसिफिकेशन्स: लिनक्स कर्नेल 3.16 ( डेबियन ) सबसे अधिक संभावना है जो बिना किसी स्वैप और वर्चुअलाइज्ड के साथ सक्षम होना चाहिए।
sysctl -w vm.overcommit_memory=2
रूट के रूप में करते हैं ; mjmwired.net/kernel/Documentation/vm/overcommit-accounting देखें । ध्यान दें कि इसके अन्य परिणाम हो सकते हैं; विशेष रूप से, बहुत बड़े कार्यक्रम (जैसे आपका वेब ब्राउज़र) सहायक कार्यक्रमों (जैसे पीडीएफ रीडर) को स्पॉन करने में विफल हो सकते हैं।