मेमोरी आउट-ऑफ-एप्लिकेशन मेमोरी के टैंडक्स से बचें


34

मुझे पता चल रहा है कि ऐन मौके पर मेरा लिनक्स बॉक्स मेमोरी से बाहर चला गया और इससे निपटने के लिए यादृच्छिक प्रक्रियाओं को तोड़ना शुरू कर दिया।

मैं उत्सुक हूं कि प्रशासक इससे बचने के लिए क्या करते हैं? क्या मेमोरी की मात्रा बढ़ाने के लिए एकमात्र उपाय है (क्या अकेले स्वैप मदद करेगा?), या इससे बचने के लिए सॉफ़्टवेयर के साथ बॉक्स सेट करने के बेहतर तरीके हैं? (यानी, कोटा, या कुछ इस तरह?)।


मुझे यहाँ एक उत्तर मिला: serverfault.com/questions/362589/… पैट्रिक प्रतिक्रिया बहुत शिक्षाप्रद है
Amaury

जवाबों:


44

डिफ़ॉल्ट रूप से लिनक्स में स्मृति प्रबंधन की कुछ हद तक मस्तिष्क-क्षतिग्रस्त अवधारणा है: यह आपको अपने सिस्टम की तुलना में अधिक मेमोरी आवंटित करने देता है, फिर मुसीबत में पड़ने पर बेतरतीब ढंग से सिर में एक गोली मारता है। (जो मारा जाता है उसका वास्तविक शब्दार्थ इससे कहीं अधिक जटिल है - Google "लिनक्स ओओएम किलर" के बारे में बहुत सारी जानकारी और तर्क के लिए कि क्या यह अच्छी या बुरी बात है)।


अपने स्मृति प्रबंधन के लिए पवित्रता के कुछ झलक बहाल करने के लिए:

  1. OOM किलर अक्षम करें ( vm.oom-kill = 0/etc/sysctl.conf में डालें )
  2. स्मृति को अक्षम करें ( vm.overcommit_memory = 2Inetc/sysctl.conf में डालें )
    ध्यान दें कि यह एक त्रिकोणीय मूल्य है: 0 = "यदि हमारे पास पर्याप्त रैम है तो अनुमान लगाएं", 1 = "हमेशा हां कहें", 2 = "हम नहीं मानें तो कहें" स्मृति है ")

ये सेटिंग्स पारंपरिक तरीके से लिनक्स का व्यवहार करेंगी (यदि कोई प्रक्रिया उपलब्ध मेमोरी से अधिक मेमोरी का अनुरोध करती है तो मॉलॉक विफल हो जाएगा) और मेमोरी का अनुरोध करने वाली प्रक्रिया उस विफलता से निपटने की उम्मीद करती है।

रीबूट करने के लिए अपनी मशीन को रिबूट करें /etc/sysctl.conf, या procरिबूट के बिना फ़ाइल सिस्टम का उपयोग करें।

echo 2 > /proc/sys/vm/overcommit_memory 

11
यह लीनियस म्यूट नहीं है, लेकिन प्रोग्रामर जो मेमोरी आवंटित करते हैं, इसका उपयोग कभी नहीं करते हैं। जावा वीएम इसके साथ कुख्यात हैं। मैं, एक व्यवस्थापक के रूप में जो जावा एप्स को चलाने वाले सर्वरों का प्रबंधन करता है, वह एक सेकंड में ओवरकॉमिट के बिना नहीं बचता।
अलेक्जेंडर इवानसेविच

11
जावा प्रोग्रामर अप्रयुक्त मेमोरी को आवंटित नहीं करते हैं, जावा में कोई मॉलोक नहीं है। मुझे लगता है कि आप इस तरह के JVM सेटिंग्स के साथ भ्रमित कर रहे हैं -Xms। किसी भी मामले में, स्वैप स्थान को जोड़कर वर्चुअल मेमोरी साइज़ को बढ़ाना ओवरकमिंग की तुलना में अधिक सुरक्षित उपाय है।
jlliagre

5
ध्यान दें कि यह समाधान आपके सिस्टम को मेमोरी से बाहर निकलने या प्रक्रियाओं को मारने से नहीं रोकेगा। यह केवल आपको पारंपरिक यूनिक्स व्यवहार में वापस लाएगा, जहां अगर एक प्रक्रिया आपकी सभी मेमोरी खाती है, तो अगले एक दिन जो मैलोडोक की कोशिश करता है उसे कोई भी (और सबसे अधिक संभावना दुर्घटना) नहीं मिलेगा। यदि आप अशुभ हैं कि अगली प्रक्रिया init (या कुछ और जो कि महत्वपूर्ण है), जिसे OOM किलर आमतौर पर टाल देता है।
पीहर

8
jlliagre, मैंने कहा जावा VMs (वर्चुअल मशीन), जावा प्रोग्राम नहीं, हालांकि एक व्यवस्थापक दृष्टिकोण से यह समान है :)
अलेक्जेंडर इवानसेविच

8
शायद यहाँ उल्लेख के लायक है कि ऊपर जोड़ने की /etc/sysctl.confसंभावना केवल अगले रिबूट पर प्रभावी होगी; आप परिवर्तन करना चाहते हैं, तो अब आप का उपयोग करना चाहिए sysctlरूट अनुमतियों जैसे के साथ आदेशsudo sysctl vm.overcommit_memory=2
nickgrim


3

एक सर्वर के लिए संक्षिप्त उत्तर, अधिक रैम खरीदना और स्थापित करना है।

एक सर्वर जो नियमित रूप से ओओएम (आउट-ऑफ-मेमोरी) त्रुटियों का अनुभव करता है, तो लिनक्स कर्नेल में वीएम (आभासी मेमोरी) प्रबंधक के ओवरक्लिट sysctl विकल्प के अलावा, यह अच्छी बात नहीं है।

स्वैप की मात्रा (वर्चुअल मेमोरी जिसे कर्नेल मेमोरी मैनेजर द्वारा डिस्क में पेज किया गया है) को ऊपर उठाने में मदद मिलेगी यदि वर्तमान मान कम हैं, और उपयोग में कई कार्य शामिल हैं, जिसमें एक या कुछ नहीं बल्कि कई बड़ी मात्रा में मेमोरी होती है। उपलब्ध कुल वर्चुअल मेमोरी (रैम + स्वैप) की एक बड़ी राशि का अनुरोध करने वाली प्रत्येक प्रक्रिया।

कई अनुप्रयोगों के लिए दो से अधिक समय (2x) आवंटित करने पर रैम की मात्रा स्वैप के रूप में सुधार पर कम रिटर्न प्रदान करती है। कुछ बड़े कम्प्यूटेशनल सिमुलेशन में, यह स्वीकार्य हो सकता है यदि गति धीमी-डाउन करने योग्य है।

रैम के साथ (ईसीसी या नहीं) मामूली मात्रा के लिए काफी सस्ती है, उदाहरण के लिए, 4-16 जीबी, मुझे स्वीकार करना होगा, मैंने लंबे समय से इस समस्या का अनुभव नहीं किया है।

स्मृति उपयोग को देखते हुए, स्मृति उपयोग द्वारा छाँटे गए freeऔर top, मेमोरी उपयोग पैटर्न के दो सबसे सामान्य त्वरित मूल्यांकन के रूप में मूल बातें । इसलिए सुनिश्चित करें कि आप उन कमांड के आउटपुट में प्रत्येक क्षेत्र का अर्थ बहुत कम से कम समझते हैं।

अनुप्रयोगों की कोई बारीकियों (जैसे डेटाबेस, नेटवर्क सेवा सर्वर, वास्तविक समय वीडियो प्रसंस्करण) और सर्वर के उपयोग (कुछ बिजली उपयोगकर्ताओं, उपयोगकर्ता / ग्राहक कनेक्शन के 100-1000s) के साथ, मैं किसी भी सामान्य सिफारिशों से निपटने के बारे में नहीं सोच सकता OOM समस्या।


3

भौतिक स्मृति की मात्रा में वृद्धि सभी परिस्थितियों में एक प्रभावी प्रतिक्रिया नहीं हो सकती है।

इसे जांचने का एक तरीका है 'एटॉप' कमांड। विशेष रूप से ये दो पंक्तियाँ।

स्वस्थ होने पर यह सर्वर से बाहर है:

MEM | tot   23.7G | free   10.0G | cache   3.9G | buff  185.4M | slab  207.8M |
SWP | tot    5.7G | free    5.7G |              | vmcom  28.1G | vmlim  27.0G |

जब यह खराब चल रहा था (और इससे पहले कि हम 50 से 90 तक overcommit_memory समायोजित कर लेते हैं, तो हम vmcom के साथ व्यवहार को 50G से अधिक अच्छी तरह से चलाते हुए देखेंगे, ऊम-किलर हर कुछ सेकंड में प्रक्रियाओं को उड़ाता है, और भार एनएफएसडी बच्चे की प्रक्रियाओं के कारण मौलिक रूप से उछलता रहता है। लगातार और फिर से बनाया गया।

हमने हाल ही में डुप्लिकेट किए गए मामलों में जहां बहु-उपयोगकर्ता लिनक्स टर्मिनल सर्वर वर्चुअल मेमोरी आवंटन को बड़े पैमाने पर करते हैं, लेकिन अनुरोधित पृष्ठों में से बहुत कम वास्तव में खपत होते हैं।

हालांकि इस सटीक मार्ग का पालन करने की सलाह नहीं दी गई है, लेकिन हमने ओवरकमिट-मेमोरी को डिफ़ॉल्ट 50 से 90 तक समायोजित कर दिया, जिससे कुछ समस्या दूर हो गई। हमने अंत में सभी उपयोगकर्ताओं को दूसरे टर्मिनल सर्वर पर ले जाने और पूरा लाभ देखने के लिए पुनरारंभ किया।


2

स्मृति की मात्रा को कम करने के लिए आप ulimit का उपयोग कर सकते हैं एक प्रक्रिया को मारने से पहले दावा करने की अनुमति है। यदि आपकी समस्या एक या कुछ दूर चलने वाली प्रक्रिया है जो आपके सर्वर को क्रैश करती है तो यह बहुत उपयोगी है।

यदि आपकी समस्या यह है कि आपके पास केवल उन सेवाओं को चलाने के लिए पर्याप्त मेमोरी नहीं है जिनकी आपको आवश्यकता है तो केवल तीन समाधान हैं:

  1. आपकी सेवाओं द्वारा उपयोग की जाने वाली मेमोरी को कैश और इसी तरह सीमित करके कम करें

  2. एक बड़ा स्वैप क्षेत्र बनाएँ। यह आपको प्रदर्शन में खर्च करेगा, लेकिन आपको कुछ समय खरीद सकता है।

  3. अधिक मेमोरी खरीदें


0

मेरे पास इस बग से संबंधित समस्या थी और समाधान पुराने / नए (निश्चित) कर्नेल का उपयोग करना था।

हालाँकि जिस समय मैं अपनी मशीन को रिबूट नहीं कर सकता था, तब किसी तरह का बदसूरत वर्कअराउंड रूट और क्लियर सिस्टम कैश के रूप में लॉगिन करना था:

echo 3 > /proc/sys/vm/drop_caches

-5

@ voretaq7 linux में स्मृति प्रबंधन की मस्तिष्क-क्षतिग्रस्त अवधारणा नहीं है, डिफ़ॉल्ट रूप से vm.overcommit_ratio 0 है,

0       -   Heuristic overcommit handling. Obvious overcommits of
            address space are refused. Used for a typical system. It
            ensures a seriously wild allocation fails while allowing
            overcommit to reduce swap usage.  root is allowed to
            allocate slightly more memory in this mode. This is the
            default.

इस तरह, यदि आपके पास 4 जीबी रैम है और आप वर्चुअल मेमोरी के मॉलोक के साथ 4.2 जीबी आवंटित करने का प्रयास करते हैं, तो आपका आवंटन विफल हो जाएगा।

Vm.overcommit_ratio = 1 के साथ

            1    -   Always overcommit. Appropriate for some scientific
            applications. Classic example is code using sparse arrays
            and just relying on the virtual memory consisting almost
            entirely of zero pages.

Vm.overcommit_ratio = 2 के साथ

           2    -   Don't overcommit. The total address space commit
            for the system is not permitted to exceed swap + a
            configurable percentage (default is 50) of physical RAM.
            Depending on the percentage you use, in most situations
            this means a process will not be killed while accessing
            pages but will receive errors on memory allocation as
            appropriate.

            Useful for applications that want to guarantee their
            memory allocations will be available in the future
            without having to initialize every page.

तो डिफ़ॉल्ट रूप से लिनक्स ओवरकॉमिट नहीं करता है, यदि आपका एप्लिकेशन अधिक मेमोरी है तो आपके पास, शायद आपका कोड छोटी गाड़ी है


2
आपने खुद को यहां प्रतिवाद किया है। शीर्ष पर आप कहते हैं "डिफ़ॉल्ट रूप से vm.overcommit_ratio 0 है" और फिर नीचे आप कहते हैं "डिफ़ॉल्ट रूप से लिनक्स नहीं आता है"। यदि उत्तरार्द्ध सत्य थे, तो vm.overcommit_ratio डिफ़ॉल्ट रूप से 2 होगा!
माइकल हैम्पटन

vm.overcommit_ratio = 0, Malloc आपके भौतिक RAM की तुलना में अधिक मेमोरी आवंटित नहीं करता है, इसलिए मेरे लिए इसका मतलब है कि
Overcommit

2
हां, आपने गलत समझा है।
माइकल हैम्पटन

आप गलत समझे, डिफ़ॉल्ट 0, राम की तुलना में अधिक आभासी मेमोरी आवंटित करने के लिए आवंटित नहीं करता है और 2 vm.overcommit_ratio + स्वैप स्थान की अनुमति नहीं देता है, इसलिए यदि मुझे गलत समझा जाए तो मुझे बताएं
c4f4x0r

2
बेशक। "स्पष्ट overcommits" मना कर दिया जाता है। बाकी गुजरता है। आपको अधिक ध्यान से पढ़ने की आवश्यकता है।
माइकल हैम्पटन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.