कैसे इस स्मृति मुद्दे को इनायत से हल करें?


10

मेरे पास एक मानक लिनक्स (डेबियन परीक्षण) लैपटॉप है, जिसमें एक स्वैप विभाजन है।

मैं इसके साथ बहुत सारे प्रयोग करता हूं। उनमें से कुछ वास्तव में भूख लगी है और लिनक्स डिफ़ॉल्ट रूप से व्यवहार करता है मेरे लिए एक मुद्दा है ... आइए एक बेवकूफ उदाहरण दें:

  1. लैपटॉप के सामने बैठो
  2. एक टर्मिनल खोलें
  3. टाइप करें python, तबa = [0]*100000000

अब संभावना अधिक है कि आपके पास उस बड़ी सूची को संभालने के लिए पर्याप्त रैम नहीं होगी। लिनक्स रैम को भर देगा, फिर स्वैप और कुछ मिनट बाद, OOM हत्यारा ट्रिगर हो जाएगा और (लगभग) यादृच्छिक सेवाओं को मार देगा और उम्मीद है, अगर आप अच्छे समय में Ctrl + C मारते हैं python, और यदि टर्मिनल अभी भी फोकस था, कंप्यूटर फिर से उत्तरदायी हो जाएगा।

मैं उस अनचाहे स्वैपिंग से बचने और एक प्रक्रिया से इंकार करने के लिए कुछ मेमोरी लिमिट लागू करना चाहता हूं, जितना कि मेरे पास (RAM में) अधिक मेमोरी आवंटित करने का अधिकार है। यदि मेमोरी डिमांड एक निश्चित सीमा से कम है या रूट द्वारा पूछा गया है, तो बस रूट को छोड़कर किसी भी उपयोगकर्ता की सबसे मेमोरी भूख प्रक्रिया को मार दें।

ulimit -Sv [mem] मैं पीछे में सुनता हूँ!

हो हो! "उपयोग cgroupsके माध्यम से cgexec!" पहली पंक्ति में कोई कहता है!

हां, आप सही हैं: ये वास्तव में बहुत अच्छे समाधान हैं। परंतु:

  • वे सिस्टम-वाइड लागू नहीं करते हैं
  • सीमाएँ प्रति-प्रक्रिया निर्धारित हैं
  • सीमाएं स्थिर हैं, वास्तविक राशि की नि: शुल्क रैम की उपेक्षा (AFAIK)
  • यहाँ और वहाँ , वे कहते हैं कि ये वास्तव में कठिन सीमाओं को लागू करने के लिए एक अच्छा समाधान नहीं हैं।

मैं यह चाहूंगा कि कर्नेल कहे: "आप उपयोगकर्ता फू (रूट नहीं) से संबंधित हैं, आप बहुत सारी मेमोरी का उपयोग करते हैं और हम मेमोरी से बाहर निकलने वाले हैं। क्षमा करें दोस्त ... अब मर जाओ!"

या: "आप क्या कर रहे हैं? आपको x MB की आवश्यकता है और केवल y MB उपलब्ध है। हां, SWAP खाली है, लेकिन आप अपने गंदे काम करने के लिए SWAP का उपयोग करने का इरादा नहीं रखते हैं, क्या आप? नहीं, मैं आपके लिए कोई स्मृति नहीं है! यदि आप जोर देते हैं, तो आप मरने वाले हैं! "


2
इस लेख में पहले से ही एक एल्गोरिथ्म वर्णित है जो OOM हत्यारे को सही प्रक्रिया चुनने में मदद करता है। परिवर्तन /proc/sys/vm/overcommit_memoryकम मेमोरी पर कर्नेल व्यवहार को प्रभावित करता है।
जोफेल

1
हां, लेकिन overcommit_memoryविशेष फ़ाइल RAM + SWAP का उपयोग करने योग्य मेमोरी के रूप में करती है। मैं अभी भी स्वैप करने जा रहा हूँ :)

1
आपको यह भी समझाने की आवश्यकता है कि यह इस बात का डुप्लिकेट नहीं है: unix.stackexchange.com/questions/34334/… जो आपको WRT cgroups और अलग-अलग उपयोगकर्ताओं को विरोधाभासी करता है। पुनश्च। यदि आप स्वैप नहीं करना चाहते हैं, तो स्वैप को अक्षम करें
गोल्डीलॉक्स

1
मुझे स्वैप चाहिए! मुझे हाइबरनेशन चाहिए, मैं अप्रयुक्त बाइट्स को दूर रखना चाहता हूं ! लेकिन मैं नहीं चाहता कि इस्तेमाल किए जाने वाले बाइट्स वहां जमा हों। लिंक के बारे में, ulimitsएक बुरा विचार है जैसा कि लगभग हर जगह दिखाया गया है क्योंकि यह एक प्रति प्रक्रिया सीमा है ... मुझे पता है कि आप के बारे में :) cgroups, यह निश्चित रूप से बेहतर है, लेकिन कुछ और सामान्य का अभाव है: मैं अपने लैपटॉप के बारे में बात कर रहा हूं लेकिन मैं भी एक "गणना" सर्वर का मालिक है जिसे हम साझा करने के लिए तीन हैं। यदि मैं ऐसी प्रति उपयोगकर्ता सीमा लागू करता हूं, तो मैं सबसे खराब स्थिति में सीमित रहूंगा, क्या मैं नहीं?

1
cgroups जो भी प्रक्रिया आप तय करते हैं उस पर लागू होते हैं- उपयोगकर्ता की सभी प्रक्रियाओं को एक अलग समूह में डालते हैं और यह वही करना चाहिए जो आप चाहते हैं।
13

जवाबों:


4

किसी ने आपके सुनने में सुझाव दिया cgroups। खैर, उस दिशा की तलाश करने की कोशिश करें क्योंकि यह आपको प्रदान कर सकती है:

  • आपके द्वारा चुने गए कार्य के एक समूह पर लागू होता है (इस प्रकार न तो प्रणाली चौड़ी होती है और न ही प्रक्रिया के अनुसार)
  • समूह के लिए सीमाएँ निर्धारित की गई हैं
  • सीमाएं स्थिर हैं
  • वे मेमोरी और / या मेमोरी + स्वैप पर हार्ड लिमिट लागू कर सकते हैं

कुछ ऐसा जो आपको अपने लक्ष्यों के करीब ला सके :

group limited {
  memory {
    memory.limit_in_bytes = 50M;
    memory.memsw.limit_in_bytes = 50M;
  }
}

यह बताता है कि इस cgroup के तहत कार्य अधिकतम 50M मेमोरी और केवल 50M मेमोरी + स्वैप का उपयोग कर सकते हैं, इसलिए जब मेमोरी भर जाती है, तो यह स्वैप नहीं करेगा, लेकिन यदि मेमोरी पूरी नहीं है और कुछ डेटा मैप किया जा सकता है स्वैप, यह अनुमति दी जा सकती है।

यहाँ cgroup की मेमोरी प्रलेखन का एक अंश दिया गया है :

यादों की सीमा का उपयोग करके, आप सिस्टम OOM से बच सकते हैं जो स्वैप की कमी के कारण हो सकता है।


अभी भी बिल्कुल वैसा नहीं जैसा मैं उम्मीद कर रहा था। लेकिन मैं क्या उम्मीद करता हूं और वास्तविकता के बीच अंतर अक्सर काफी बड़ा होता है :) इस मामले में, मैं यह सुनिश्चित करना चाहता था कि मैं overcommit_memoryकर्नेल चर की तरह कुछ भी याद नहीं करता। आप सभी को धन्यवाद।

0

मैं एक ही समस्या में अक्सर चला जाता हूं। मेरे सामान्य वर्कफ़्लो में MATLAB में भारी गणना शामिल है। कभी-कभी मैं अनजाने में एक नए चर को आवंटित करने का प्रयास करूंगा जो उपलब्ध स्मृति की मात्रा से अधिक है। सिस्टम लटका हुआ है, और मुझे आमतौर पर काम पर वापस जाने के लिए मशीन को हार्ड-रिबूट करना पड़ता है। : पी

मेरे मामले में, और यह भी आपकी तरह लगता है, मैं एक स्थिर राशि के लिए MATLAB उपयोग की मात्रा को सीमित करने के साथ इतना चिंतित नहीं था - मैं एक जमे हुए मशीन नहीं होने में रुचि रखता था, और मैं अपनी MATLAB प्रक्रिया का त्याग करने के लिए तैयार था सिस्टम की जवाबदेही को बनाए रखने के लिए।

इस पोस्ट की प्रतिक्रिया से प्रेरित होकर , मैंने निम्नलिखित स्क्रिप्ट लिखी (मैंने इसे watch_memory.sh कहा):

#!/bin/bash

MONITOR=$(free | grep 'buffers/cache:')
MEM_USED=$(echo $MONITOR | awk '{ print $3 }')
MEM_FREE=$(echo $MONITOR | awk '{ print $4 }')

MEM_PERC=$(( 100*MEM_USED / (MEM_FREE+MEM_USED) ))

while :; do
    if [ "$MEM_PERC" -gt "95" ]
    then
        kill $1
        echo "$1 killed for using too much memory."
        exit
    fi
    sleep 1

    MONITOR=$(free | grep 'buffers/cache:')
    MEM_USED=$(echo $MONITOR | awk '{ print $3 }')
    MEM_FREE=$(echo $MONITOR | awk '{ print $4 }')
    MEM_PERC=$(( 100*MEM_USED / (MEM_FREE+MEM_USED) ))
done

यह स्क्रिप्ट मुफ्त मेमोरी की प्रतिशत राशि के लिए हर सेकंड की जाँच करती है। जब सिस्टम खत्म हो जाता है, तो आपका "बलि का बकरा" पीआईडी ​​(स्क्रिप्ट के तर्क के रूप में पारित) मारा जाता है।

स्क्रिप्ट की प्राथमिकता (निष्पक्षता) को समायोजित किए बिना, बलि देने वाले को मारने के लिए लगभग 10-20 सेकंड लगते थे, लेकिन फिर भी उसने काम किया। नकारात्मक प्राथमिकता के साथ स्क्रिप्ट को चलाने से उल्लंघन के बाद एक त्वरित हत्या हुई (इस उदाहरण में 11916 है कि अगर मैं स्मृति से बाहर चला जाऊं तो मैं मारना चाहता हूं):

sudo nice -n -5 bash watch_memory.sh 11916
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.