Vm.overcommit_memory कैसे काम करता है?


49

जब मैं डिफ़ॉल्ट सेटिंग्स का उपयोग करता हूं:

vm.overcommit_memory = 0
vm.overcommit_ratio = 50

मैं इन मानों को /proc/meminfoफ़ाइल से पढ़ सकता हूं :

CommitLimit:     2609604 kB
Committed_AS:    1579976 kB

लेकिन जब मैं बदलने vm.overcommit_memoryसे 0करने के लिए 2, मैं अनुप्रयोगों है कि मैं बदलने से पहले शुरू कर सकता है के एक ही सेट शुरू करने में असमर्थ हूँ, विशेष रूप से Amarok। मैं बदलना पड़ा vm.overcommit_ratioकरने के लिए 300है, तो सीमा को बढ़ाया जा सकता है। अब जब मैं अमारोक शुरू करता हूं, /proc/meminfoतो निम्न दिखाता है:

CommitLimit:     5171884 kB
Committed_AS:    3929668 kB

इस मशीन में केवल 1GiB RAM है, लेकिन vm.overcommit_memory0. के सेट होने 2पर amarok समस्याओं के बिना काम करता है। लेकिन इसे सेट करने के मामले में , amarok को 2GiB से अधिक मेमोरी आवंटित करने की आवश्यकता होती है। क्या यह एक सामान्य व्यवहार है? यदि हां, तो क्या कोई यह बता सकता है कि, उदाहरण के लिए, फ़ायरफ़ॉक्स (जो एमारॉक की तुलना में 4-6 गुना अधिक मेमोरी का उपभोग करता है) परिवर्तन से पहले और बाद में उसी तरह से काम करता है?

जवाबों:


66

आप man 5 proc( या कर्नेल में ) प्रलेखन पा सकते हैं :

/proc/sys/vm/overcommit_memory
       This file contains the kernel virtual memory accounting mode.
       Values are:

              0: heuristic overcommit (this is the default)
              1: always overcommit, never check
              2: always check, never overcommit

       In mode 0, calls of mmap(2) with MAP_NORESERVE are not
       checked, and the default check is very weak, leading to the
       risk of getting a process "OOM-killed".

       In mode 2 (available since Linux 2.6), the total virtual
       address space that can be allocated (CommitLimit in /proc/mem‐
       info) is calculated as

           CommitLimit = (total_RAM - total_huge_TLB) *
                         overcommit_ratio / 100 + total_swap

इसका सरल उत्तर यह है कि 1 को ओवरकॉमिट करना, स्टेज को सेट कर देगा ताकि जब कोई प्रोग्राम किसी चीज malloc()को मेमोरी का एक हिस्सा आवंटित करने के लिए कहे ( man 3 malloc), तो यह हमेशा सफल होगा, भले ही सिस्टम को पता हो कि उसमें वह सारी मेमोरी नहीं होगी जो हो रही है के लिए पूछा।

समझने के लिए अंतर्निहित अवधारणा आभासी स्मृति का विचार है । प्रोग्राम एक वर्चुअल एड्रेस स्पेस देखते हैं जो वास्तविक भौतिक मेमोरी में मैप किया जा सकता है या नहीं। Overcommit जाँच को अक्षम करके, आप OS को यह मानने के लिए कहते हैं कि वर्चुअल स्पेस का बैकअप लेने के लिए हमेशा पर्याप्त भौतिक मेमोरी होती है।

उदाहरण

यह उजागर करने के लिए कि यह कभी-कभी क्यों हो सकता है, रेडिस के दिशानिर्देशों पर एक नज़र डालें कि vm.overcommit_memoryइसके लिए 1 को क्यों सेट किया जाना चाहिए।


2
लेकिन क्या Committed_ASदोनों मामलों में समान नहीं होना चाहिए ?
मिखाइल मोरफिकोव

@ मिखाइलमॉर्फिकोव: सिद्धांत रूप में, मैं ऐसा मानता हूं, लेकिन कौन जानता है कि ये कार्यक्रम क्या कर रहे हैं। एक साधारण प्रोग्राम के साथ एक अधिक नियंत्रित वातावरण देखना चाहते हैं जो कि मल्को के माध्यम से राम के एक टमटम को आवंटित करता है। और फिर परीक्षणों के बीच रिबूट करने के बाद परीक्षण चलाएं।
काइल ब्रान्ड

ठीक है, इसलिए मैं 0अभी साथ रहूंगा ।
मिखाइल मोरफिकोव

2
@ मिखाइलमॉर्फिकोव: हां, व्यावहारिक रूप से मुझे लगता है कि 0 सबसे अधिक समझ में आता है। मेरे वातावरण में, मैं केवल 1 सक्षम करता हूं रेडिस के लिए, जो सामान करता है जहां यह अपेक्षा करता है कि यह बहुत अधिक मेमोरी के लिए पूछ रहा है जो कि कांटा () के कारण उपयोग कर रहा है। बच्चा बहुत सारे समान मेमोरी पेजों का उपयोग करेगा, लेकिन लिनक्स यह नहीं जानता है कि सुरक्षित होने के लिए यह कहता है कि इसे 2x मेमोरी का उपयोग करना होगा (यदि आप अधिक सीखना चाहते हैं: redis.io/topics/faq )
काइल ब्रैंड

क्या आपके उत्तर का अंतिम विवरण "ओवरकमिट को सक्षम करके" शुरू नहीं होना चाहिए? क्योंकि इसे 1 पर सेट करने का मतलब है कि आप इसे ओवरकमिट करने के लिए कह रहे हैं, है ना?
asgs
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.