मैं वितरण के दौरान उपलब्ध स्मृति की मात्रा को आंशिक रूप से कैसे प्राप्त कर सकता हूं?


12

मेमोरी की रिपोर्ट करने वाली मानक फाइलें / उपकरण विभिन्न लिनक्स वितरण पर अलग-अलग प्रारूप हैं। उदाहरण के लिए, आर्क और उबंटू पर।

  • मेहराब

    $ free
                  total        used        free      shared  buff/cache   available
    Mem:        8169312     3870392     2648348       97884     1650572     4110336
    Swap:      16777212      389588    16387624
    
    
    $ head /proc/meminfo 
    MemTotal:        8169312 kB
    MemFree:         2625668 kB
    MemAvailable:    4088520 kB
    Buffers:          239688 kB
    Cached:          1224520 kB
    SwapCached:        17452 kB
    Active:          4074548 kB
    Inactive:        1035716 kB
    Active(anon):    3247948 kB
    Inactive(anon):   497684 kB
    
  • उबंटू

    $ free
                 total       used       free     shared    buffers     cached
    Mem:      80642828   69076080   11566748    3063796     150688   58358264
    -/+ buffers/cache:   10567128   70075700
    Swap:     20971516    5828472   15143044
    
    
    $ head /proc/meminfo 
    MemTotal:       80642828 kB
    MemFree:        11565936 kB
    Buffers:          150688 kB
    Cached:         58358264 kB
    SwapCached:      2173912 kB
    Active:         27305364 kB
    Inactive:       40004480 kB
    Active(anon):    7584320 kB
    Inactive(anon):  4280400 kB
    Active(file):   19721044 kB
    

इसलिए, मैं कैसे (केवल लिनक्स डिस्ट्रोस के पार) पोर्टिकली और मज़बूती से मेमोरी की मात्रा प्राप्त कर सकता हूँ — जो कि एक विशेष समय पर उपयोग करने के लिए मेरे सॉफ़्टवेयर के लिए उपलब्ध है? संभवत: वही है जो आर्क में freeऔर उसके आउटपुट में "उपलब्ध" और "मेमअवेलेबल" के रूप में दिखाया गया है cat /proc/meminfoलेकिन मुझे उबंटू या अन्य वितरण में समान कैसे मिलेगा?

जवाबों:


18

MemAvailable/proc/meminfoकर्नेल के संस्करण 3.14 से शामिल है ; यह प्रतिबद्ध 34e431b0a द्वारा जोड़ा गया था । यह आपके द्वारा दिखाए जाने वाले आउटपुट विविधताओं का निर्धारण कारक है। प्रतिबद्ध संदेश इंगित करता है कि बिना उपलब्ध स्मृति का अनुमान कैसे लगाया जाए MemAvailable:

वर्तमान में, स्मृति की मात्रा है कि एक नए काम का बोझ के लिए उपलब्ध है, स्वैप में प्रणाली भेजे बिना, से अनुमान लगाया जा सकता MemFree, Active(file), Inactive(file), और SReclaimableसे, साथ ही "कम" वॉटरमार्क /proc/zoneinfo

निम्न वॉटरमार्क एक स्तर है जिसके नीचे सिस्टम स्वैप होगा। तो के अभाव में MemAvailableआप कम से कम के लिए दिए गए मान को जोड़ सकते हैं MemFree, Active(file), Inactive(file)और SReclaimable(वर्तमान में कर रहे हैं, जो भी /proc/meminfo), और से कम वॉटरमार्क घटाना /proc/zoneinfo। उत्तरार्द्ध भी प्रति क्षेत्र मुक्त पृष्ठों की संख्या को सूचीबद्ध करता है, जो एक तुलना के रूप में उपयोगी हो सकता है ...

पूरा एल्गोरिथ्म पैच में दिया गया है meminfo.cऔर अनुकूल रूप से आसान लगता है:

  • सभी क्षेत्रों में कम वॉटरमार्क की राशि;
  • पहचानी गई मुफ्त मेमोरी ( MemFree) लें;
  • कम वॉटरमार्क घटाएं (हमें स्वैपिंग से बचने के लिए इसे छूने से बचने की आवश्यकता है);
  • वह मेमोरी जो हम पेज कैश से उपयोग कर सकते हैं (राशि Active(file)और Inactive(file)) जोड़ दें : यह पेज कैश द्वारा उपयोग की जाने वाली मेमोरी की मात्रा है, या तो आधे पेज कैश, या कम वॉटरमार्क, जो भी छोटा हो;
  • SReclaimableउसी एल्गोरिथ्म का अनुसरण करते हुए हम जितनी मेमोरी पुनः प्राप्त कर सकते हैं ( ) जोड़ें ।

तो, यह सब एक साथ रखकर, आप एक नई प्रक्रिया के लिए उपलब्ध स्मृति प्राप्त कर सकते हैं:

awk -v low=$(grep low /proc/zoneinfo | awk '{k+=$2}END{print k}') \
 '{a[$1]=$2}
  END{ 
   print a["MemFree:"]+a["Active(file):"]+a["Inactive(file):"]+a["SReclaimable:"]-(12*low); 
  }' /proc/meminfo 

आह, अच्छा है, तो कम से कम यह एक ही कर्नेल संस्करण में पोर्टेबल होना चाहिए। यह कुछ है। मैं आपके सुझाव का परीक्षण कर रहा हूं, awk -v low=$(grep low /proc/zoneinfo | awk '{k+=$2}END{print k}') '{a[$1]=$2}END{m=a["MemFree:"]+a["Active(file):"]+a["Inactive(file):"]+a["SReclaimable:"]; print a["MemAvailable:"],m-low}' /proc/meminfoजिसके साथ मुझे दो बार छपी उसी संख्या को देना चाहिए। हालांकि, दूसरी संख्या (आपके द्वारा सुझाए गए एल्गोरिथम की मेरी समझ) में MemAvailableदिखाए गए से अधिक है /proc/meminfo। मैं क्या गलत कर रहा हूं?
terdon

2
/proc/zoneinfoउन पृष्ठों को गिनता है, जो आकार में अधिकतर 4KB हैं amd64; आप पेज कैश और पुनः प्राप्त मेमोरी में जोड़े गए अतिरिक्त सुरक्षा को भी याद कर रहे हैं। उत्तरार्द्ध को सरल करते हुए, हम कम वॉटरमार्क को तीन बार घटा सकते हैं, इसलिए m-12*low(3 × 4KB) मेरे सिस्टम पर सही परिणाम देता है। (यह सरलीकरण उपलब्ध मेमोरी को कम कर देता है यदि पेज कैश या रीक्लेमेबल मेमोरी कम वॉटरमार्क से दोगुना है, लेकिन आप उस स्थिति में बहुत मेमोरी का उपयोग नहीं करना चाहेंगे, ताकि यह एक उचित समझौता हो।)
स्टीफन किट

1
@StephenKitt आप पुराने कर्नेल के लिए इसकी गणना कैसे करेंगे जिनके पास (file)या तो SReclaimableप्रविष्टि नहीं है या प्रवेश नहीं है? कर्नेल v 2.6.18-348.16.1.el5xen (प्रति uname -r) के साथ एक पुराने सेंटो बॉक्स पर यह मुझे मिलने वाला आउटपुट है: pastebin.com/iFWiM1kX । आपकी गणना केवल MemFreeभाग को खींचती है
मिच

@ मुझे नहीं पता, मुझे यकीन नहीं है कि आपके पुराने कर्नेल से उपलब्ध जानकारी उपलब्ध मेमोरी (स्वैप करने से पहले) को सटीक रूप से निर्धारित करने के लिए पर्याप्त है।
स्टीफन किट

इस धागे में योगदान करने वाले सभी लोगों के लिए धन्यवाद, यह एक महान संदर्भ है। MemAvailable की गणना को Linux 4.5 में थोड़ा समायोजित किया गया है। हालाँकि, नया मेमवैल्यूअल कैलकुलेशन हमेशा पुराने वाले की तुलना में थोड़ा अधिक (या शायद उतना ही) होना चाहिए, इसलिए सभी मामलों में पुरानी गणना का उपयोग करना सुरक्षित होना चाहिए। gitlab.com/procps-ng/procps/issues/42
sourcejedi

7

जबकि स्टीफन का जवाब पूरी तरह से पर्याप्त है और सावधानी के पक्ष में गलतियां हैं, मैंने न्यूनतम तुलनाओं सहित पूर्ण तर्क को लिखने का फैसला किया। सूचना को पहले / proc / meminfo से पढ़ा जाता है और एक चर में संग्रहीत किया जाता है ताकि स्मृति विवरण सुसंगत हो।

LOW_WATERMARK=$(awk '$1 == "low" {LOW_WATERMARK += $2} END {print LOW_WATERMARK * 4096}' /proc/zoneinfo)

MEMINFO=$(</proc/meminfo)

MEMINFO_MEMFREE=$(echo "${MEMINFO}" | awk '$1 == "MemFree:" {print $2 * 1024}')
MEMINFO_FILE=$(echo "${MEMINFO}" | awk '{MEMINFO[$1]=$2} END {print (MEMINFO["Active(file):"] + MEMINFO["Inactive(file):"]) * 1024}')
MEMINFO_SRECLAIMABLE=$(echo "${MEMINFO}" | awk '$1 == "SReclaimable:" {print $2 * 1024}')

MEMINFO_MEMAVAILABLE=$((
  MEMINFO_MEMFREE - LOW_WATERMARK
  + MEMINFO_FILE - ((MEMINFO_FILE/2) < LOW_WATERMARK ? (MEMINFO_FILE/2) : LOW_WATERMARK)
  + MEMINFO_SRECLAIMABLE - ((MEMINFO_SRECLAIMABLE/2) < LOW_WATERMARK ? (MEMINFO_SRECLAIMABLE/2) : LOW_WATERMARK)
))

if [[ "${MEMINFO_MEMAVAILABLE}" -le 0 ]]
then
  MEMINFO_MEMAVAILABLE=0
fi

चर में संग्रहीत परिणाम बाइट्स में है।


जबकि यह उत्तर कमिटमेंट 34e431b0a में गणना को लागू करता है, स्टीफन किट के उत्तर ने 5 में से 2 मशीनों पर अधिक सटीक अनुमान प्रदान किया जो मैंने परीक्षण किया था। सभी 5 मशीनों पर, दोनों जवाब ने मेवावेल की तुलना में बड़े अनुमान दिए, जो सीधे / proc / meminfo से पढ़े गए थे। संभवतः एक सुरक्षित तरीका 2 के बीच छोटे को प्राप्त करना है, और 0.95 या तो गुणा करना है।
टॉडविज़
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.