मैं कोई कर्नेल डेवलपर नहीं हूं लेकिन मैंने इस मुद्दे पर दार्शनिक होने में वर्षों बिताए क्योंकि मैं कई बार इस सू में भाग गया। मैं वास्तव में पूरी स्थिति के लिए एक रूपक के साथ आया था इसलिए मुझे आपको बताना चाहिए। मैं अपनी कहानी में मानता हूँ कि "स्वैप" जैसी चीजें मौजूद नहीं हैं। स्वैप इन दिनों 32 जीबी रैम के साथ ज्यादा मायने नहीं रखता है।
अपने आस-पास के क्षेत्र की कल्पना करें जहां पाइप के माध्यम से प्रत्येक भवन से पानी जुड़ा हुआ है और शहरों को क्षमता का प्रबंधन करने की आवश्यकता है। मान लें कि आपके पास प्रति सेकंड केवल 100 यूनिट पानी का उत्पादन है (और सभी अप्रयुक्त क्षमता बेकार चली जाती है क्योंकि आपके पास जलाशय टैंक नहीं हैं)। प्रत्येक घर (घर = एक छोटा ऐप, एक टर्मिनल, घड़ी विजेट, आदि) को प्रति सेकंड 1 यूनिट पानी की आवश्यकता होती है। यह सब अच्छा और अच्छा है क्योंकि आपकी आबादी 90 की तरह है इसलिए सभी को पर्याप्त पानी मिलता है।
अब महापौर (= आप) तय करते हैं कि आप एक बड़ा रेस्तरां (= ब्राउज़र) खोलना चाहते हैं। यह रेस्तरां कई रसोइयों (= ब्राउज़र टैब) का निर्माण करेगा। प्रत्येक कुक को प्रति सेकंड 1 यूनिट पानी की आवश्यकता होती है। आप 10 रसोइयों के साथ शुरू करते हैं, इसलिए पूरे पड़ोस के लिए पानी की कुल खपत 100 यूनिट पानी है जो अभी भी सभी अच्छा है।
अब मज़ेदार सामग्री शुरू होती है: आप अपने रेस्तरां में एक और कुक को किराए पर लेते हैं जो पानी की कुल आवश्यकताओं को 101 बनाता है जो जाहिर है आपके पास नहीं है। आपको कुछ करने की जरूरत है।
जल प्रबंधन (= कर्नेल) में 3 विकल्प हैं।
1. पहला विकल्प सिर्फ उन घरों के लिए सेवा को डिस्कनेक्ट करना है जिन्होंने हाल ही में पानी का उपयोग नहीं किया था। यह ठीक है लेकिन अगर डिस्कनेक्ट किए गए घर फिर से पानी का उपयोग करना चाहते हैं, तो उन्हें फिर से लंबी पंजीकरण प्रक्रिया से गुजरना होगा। अधिक जल संसाधनों को मुक्त करने के लिए प्रबंधन कई घरों को काट सकता है। दरअसल, वे उन सभी घरों को काट देंगे, जिनमें हाल ही में पानी का उपयोग नहीं किया गया था और इस तरह कुछ मात्रा में मुफ्त पानी हमेशा उपलब्ध था।
यद्यपि आपका शहर कार्यशील रहता है, लेकिन नकारात्मक पक्ष यह है कि प्रगति रुक जाती है। आपका अधिकांश समय आपकी सेवा को बहाल करने के लिए जल प्रबंधन पर इंतजार करने में व्यतीत होता है।
फ़ाइल-समर्थित पृष्ठों के साथ कर्नेल क्या करता है। यदि आप एक बड़े निष्पादन योग्य (जैसे क्रोम) चलाते हैं, तो इसकी फ़ाइल मेमोरी की प्रतिलिपि बनाई जाती है। जब मेमोरी पर कम या यदि ऐसे हिस्से हैं जिन्हें हाल ही में एक्सेस नहीं किया गया है, तो कर्नेल उन हिस्सों को छोड़ सकता है क्योंकि यह डिस्क वैसे भी उन्हें फिर से लोड कर सकता है। यदि यह अत्यधिक रूप से किया जाता है, तो यह आपके डेस्कटॉप को रोक देता है क्योंकि सब कुछ बस डिस्क IO की प्रतीक्षा कर रहा होगा। ध्यान दें कि कर्नेल कम से कम हाल ही में उपयोग किए गए पृष्ठों को भी छोड़ देगा जब आप बहुत अधिक आईओ करना शुरू करते हैं। यही कारण है कि आपको डीवीडी छवियों जैसी कई बड़ी फ़ाइलों की प्रतिलिपि बनाने के बाद एक पृष्ठभूमि ऐप पर स्विच करने में उम्र लगती है।
यह मेरे लिए सबसे कष्टप्रद व्यवहार है क्योंकि मुझे हिकअप से नफरत है और आपका इस पर कोई नियंत्रण नहीं है। इसे बंद करने में सक्षम होना अच्छा होगा। मैं कुछ की तर्ज पर सोच रहा हूं
sed -i 's/may_unmap = 1/may_unmap = (vm_swappiness >= 0)/' mm/vmscan.c
और फिर आप इसे अक्षम करने के लिए vm_swappiness -1 को सेट कर सकते हैं। यह मेरे छोटे परीक्षणों में काफी अच्छी तरह से काम किया है, लेकिन अफसोस मैं कोई कर्नेल डेवलपर नहीं हूं, इसलिए मैंने इसे किसी को नहीं भेजा (और जाहिर है कि ऊपर थोड़ा संशोधन पूरा नहीं हुआ है)।
2।प्रबंधन पानी के लिए नए कुक के अनुरोध को अस्वीकार कर सकता है। यह शुरू में एक अच्छा विचार लगता है। हालांकि दो डाउनसाइड हैं। सबसे पहले, ऐसी कंपनियां हैं जो बहुत से पानी के सब्सक्रिप्शन का अनुरोध करती हैं, भले ही वे उनका उपयोग न करें। ऐसा करने का एक संभावित कारण यह है कि जब भी उन्हें कुछ अतिरिक्त पानी की आवश्यकता हो तो जल प्रबंधन से बात करने से बचें। दिन के समय के आधार पर उनके पानी का उपयोग ऊपर और नीचे जाता है। जैसे रेस्तरां के मामले में, कंपनी को आधी रात की तुलना में दोपहर के दौरान बहुत अधिक पानी की आवश्यकता होती है। इसलिए वे सभी संभावित पानी का अनुरोध करते हैं जो वे उपयोग कर सकते हैं लेकिन वह पानी के आवंटन को आधी रात के दौरान बर्बाद कर देता है। समस्या यह है कि सभी कंपनियां अपने शिखर के उपयोग को सही ढंग से नहीं कर सकती हैं, इसलिए वे बहुत अधिक अनुरोध करते हैं कि वे कभी भी अधिक अनुरोध करने के बारे में चिंता करने की आवश्यकता नहीं होगी।
यह वही है जो जावा की वर्चुअल मशीन करती है: यह स्टार्टअप पर मेमोरी का एक गुच्छा आवंटित करता है और फिर उसी से काम करता है। डिफ़ॉल्ट रूप से कर्नेल केवल मेमोरी आवंटित करेगा जब आपका जावा ऐप वास्तव में इसका उपयोग करना शुरू कर देगा। हालाँकि यदि आप ओवरकॉमिट को अक्षम करते हैं, तो कर्नेल आरक्षण को गंभीरता से लेगा। यह केवल आवंटन को सफल होने की अनुमति देगा यदि इसके पास वास्तव में इसके लिए संसाधन हैं।
हालांकि, इस दृष्टिकोण के साथ एक और गंभीर समस्या है। मान लीजिए कि एक कंपनी हर दिन (10 के चरणों के बजाय) पानी की एक इकाई का अनुरोध करना शुरू करती है। आखिरकार आप एक ऐसी स्थिति में पहुंच जाएंगे जहां आपके पास 0 निःशुल्क इकाइयां हैं। अब यह कंपनी अधिक आवंटन नहीं कर पाएगी। यह ठीक है, जो वैसे भी बड़ी कंपनियों के बारे में परवाह करता है। लेकिन समस्या यह है कि छोटे घर या तो अधिक पानी का अनुरोध नहीं कर पाएंगे! पर्यटकों की अचानक आमद से निपटने के लिए आप छोटे सार्वजनिक बाथरूम का निर्माण नहीं कर पाएंगे। आप पास के जंगल में आग लगने पर आपातकालीन पानी नहीं दे पाएंगे।
कंप्यूटर के संदर्भ में: बहुत कम स्मृति स्थितियों में ओवरकॉमिट के बिना आप एक नया xterm नहीं खोल पाएंगे, आप अपनी मशीन में ssh नहीं कर पाएंगे, आप संभव के लिए खोज करने के लिए एक नया टैब नहीं खोल पाएंगे फिक्स। दूसरे शब्दों में, ओवरकमिट को निष्क्रिय करने से भी मेमोरी कम होने पर आपका डेस्कटॉप बेकार हो जाता है।
3. अब यहां समस्या से निपटने का एक दिलचस्प तरीका है जब कोई कंपनी बहुत अधिक पानी का उपयोग करना शुरू करती है। जल प्रबंधन ने इसे उड़ा दिया! शाब्दिक रूप से: यह रेस्तरां की साइट पर जाता है, इसमें डायनामाइट्स फेंकता है और जब तक यह फट नहीं जाता तब तक इंतजार करता है। यह शहर की पानी की आवश्यकताओं को तुरंत बहुत कम कर देगा ताकि नए लोग आगे बढ़ सकें, आप सार्वजनिक बाथरूम आदि बना सकते हैं। आप, मेयर के रूप में, इस उम्मीद में रेस्तरां का पुनर्निर्माण कर सकते हैं कि इस बार कम पानी की आवश्यकता होगी। उदाहरण के लिए, आप लोगों से कहेंगे कि अगर वे पहले से ही बहुत से लोगों के अंदर हैं (जैसे आप कम ब्राउज़र टैब खोलेंगे) तो रेस्तरां में न जाएं।
यह वास्तव में क्या होता है जब कर्नेल सभी विकल्पों से बाहर निकलता है और उसे मेमोरी की आवश्यकता होती है: इसे OOM किलर कहता है। यह एक बड़ा अनुप्रयोग चुनता है (कई उत्तराधिकारियों के आधार पर) और इसे मारता है, स्मृति के गुच्छा को मुक्त करता है लेकिन एक उत्तरदायी डेस्कटॉप को बनाए रखता है। दरअसल एंड्रॉइड कर्नेल इसे और भी आक्रामक तरीके से करता है: यह कम से कम हाल ही में उपयोग किए गए ऐप को मारता है जब मेमोरी कम होती है (स्टॉक कर्नेल की तुलना में जो इसे केवल अंतिम उपाय के रूप में करता है)। इसे Android में वाइकिंग किलर कहा जाता है।
मुझे लगता है कि यह समस्या का सबसे सरल समाधान है: ऐसा नहीं है कि आपके पास इससे अधिक विकल्प हैं इसलिए इसे बाद में जितनी जल्दी हो सके, ठीक है? समस्या यह है कि कर्नेल कभी-कभी OOM किलर से बचने के लिए काफी काम करता है। इसलिए आप देखते हैं कि आपका डेस्कटॉप बहुत धीमा है और कर्नेल इसके बारे में कुछ नहीं कर रहा है। लेकिन सौभाग्य से ओओएम हत्यारे को खुद को लागू करने का एक विकल्प है! सबसे पहले, सुनिश्चित करें कि जादू sysrq कुंजी सक्षम है (जैसे echo 1 | sudo tee
/proc/sys/kernel/sysrq
) तब जब भी आपको लगे कि कर्नेल मेमोरी पर कम चल रहा है, तो बस Alt + SysRQ, Alt + f दबाएं।
ठीक है तो यह सब अच्छा है लेकिन आप इसे आज़माना चाहते हैं? कम स्मृति स्थिति प्रजनन के लिए बहुत सरल है। मेरे पास इसके लिए बहुत ही सरल ऐप है। आपको इसे दो बार चलाने की आवश्यकता होगी। पहला रन यह निर्धारित करेगा कि आपके पास कितनी मुफ्त रैम है, दूसरा रन कम मेमोरी की स्थिति पैदा करेगा। ध्यान दें कि यह विधि मानती है कि आपने स्वैप अक्षम किया है (उदाहरण के लिए a sudo swapoff -a
)। कोड और उपयोग इस प्रकार है:
// gcc -std=c99 -Wall -Wextra -Werror -g -o eatmem eatmem.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char** argv)
{
int limit = 123456789;
if (argc >= 2) {
limit = atoi(argv[1]);
}
setbuf(stdout, NULL);
for (int i = 1; i <= limit; i++) {
memset(malloc(1 << 20), 1, 1 << 20);
printf("\rAllocated %5d MiB.", i);
}
sleep(10000);
return 0;
}
और यहां बताया गया है कि आप इसका उपयोग कैसे करते हैं:
$ gcc -std=c99 -Wall -Wextra -Werror -g -o eatmem eatmem.c
$ ./eatmem
Allocated 31118 MiB.Killed
$ ./eatmem 31110
Allocated 31110 MiB.Killed
पहले मंगलाचरण से पता चला कि हमारे पास 31,118 MiB मुफ्त रैम है। इसलिए मैंने एप्लिकेशन को 31,110 MiB RAM आवंटित करने के लिए कहा, ताकि कर्नेल इसे मार न दे, लेकिन लगभग मेरी सारी मेमोरी खा जाए। मेरा सिस्टम जम गया: यहां तक कि माउस पॉइंटर भी हिलता नहीं था। मैंने Alt + SysRQ, Alt + f दबाया है और इसने मेरी खाने की प्रक्रिया को मार दिया है और सिस्टम बहाल हो गया है।
भले ही हम अपने विकल्पों को कम स्मृति स्थिति में करते हैं, लेकिन सबसे अच्छा तरीका (किसी भी अन्य खतरनाक स्थिति की तरह) पहली जगह में इससे बचना है। इसे करने के कई तरीके हैं। एक सामान्य तरीका जो मैंने देखा है वह है कि दुर्व्यवहार के अनुप्रयोगों (जैसे ब्राउज़रों) को बाकी सिस्टम की तुलना में अलग-अलग कंटेनरों में डाल दिया जाए। उस स्थिति में ब्राउज़र आपके डेस्कटॉप को प्रभावित नहीं कर पाएगा। लेकिन खुद को रोकना सवाल के दायरे से बाहर है इसलिए मैं इसके बारे में नहीं लिखूंगा।
टीएल; डीआर: हालांकि वर्तमान में पेजिंग से पूरी तरह से बचने का कोई तरीका नहीं है, आप ओवरकमिटी को अक्षम करके पूर्ण प्रणाली-ठहराव को कम कर सकते हैं। लेकिन कम-मेमोरी स्थिति के दौरान लेकिन एक अलग तरीके से आपका सिस्टम अभी भी अनुपयोगी रहेगा। उपरोक्त के बावजूद, कम-मेमोरी स्थिति में कर्नेल के चयन की एक बड़ी प्रक्रिया को मारने के लिए Alt + SysRQ, Alt + f दबाएं। आपके सिस्टम को कुछ सेकंड के बाद अपनी जवाबदेही को बहाल करना चाहिए। यह मानता है कि आपके पास मैजिक sysrq कुंजी सक्षम है (यह डिफ़ॉल्ट रूप से नहीं है)।