मैं जल्दी से एक प्रक्रिया को कैसे रोक सकता हूं जो थ्रैशिंग का कारण बन रहा है (अतिरिक्त मेमोरी आवंटन के कारण)?


18

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

मैंने हाल ही में अपने उबंटू लैपटॉप पर एक मैटलैब स्क्रिप्ट के कारण इसका अनुभव किया, जो एक बहुत बड़ी मैट्रिक्स को आवंटित करने की कोशिश कर रहा था। ~ 5 मिनट के जोर देने के बाद, मैं Ctrl-F1 को कंसोल और मार्लब को मारने में सक्षम था। मेरे पास कुछ हॉट-की होगी, जिसने मुझे तुरंत सिस्टम का नियंत्रण दिया होगा और मुझे आक्रामक प्रक्रिया को मारने की अनुमति दी होगी; या, शायद, बस चुपचाप इतने बड़े बफर को आवंटित करने से इनकार करते हैं।

  1. अत्यधिक स्वैपिंग के कारण गैर-जिम्मेदार या बेहद सुस्त हो चुके लिनक्स सिस्टम पर नियंत्रण पाने का सबसे तेज़ तरीका क्या है?

  2. क्या इस तरह की अदला-बदली को रोकने के लिए एक प्रभावी तरीका है, उदाहरण के लिए, स्मृति की मात्रा को सीमित करके एक प्रक्रिया को आवंटित करने की कोशिश करने की अनुमति है?

जवाबों:


11

दबाएँ Alt-SysRq-एफ सबसे स्मृति का उपयोग करके इस प्रक्रिया को मारने के लिए:

  • SysRq कुंजी आमतौर पर प्रिंट कुंजी के लिए मैप की जाती है।
  • यदि आप एक ग्राफ़िकल डेस्कटॉप का उपयोग कर रहे हैं तो आपको प्रेस करने की आवश्यकता हो सकती है Ctrl-Alt-SysRq-एफ मामले में दबाने Alt-SysRq एक और कार्रवाई को ट्रिगर करता है (जैसे स्नैपशॉट प्रोग्राम)।
  • यदि आप एक लैपटॉप का उपयोग कर रहे हैं, तो आपको एक फ़ंक्शन कुंजी भी दबाने की आवश्यकता हो सकती है।
  • अधिक जानकारी के लिए पढ़ें विकिपीडिया लेख

4

मैंने इस उद्देश्य के लिए एक स्क्रिप्ट बनाई है - https://github.com/tobixen/thrash-protect

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

बेशक, "अधिक मेमोरी खरीदें" या "स्वैप का उपयोग न करें" दो वैकल्पिक हैं, प्रश्न पर पारंपरिक जवाब "थ्रैशिंग से कैसे बचें?", लेकिन सामान्य तौर पर वे इतनी अच्छी तरह से काम नहीं करते हैं (अधिक मेमोरी स्थापित करना) गैर-तुच्छ हो, एक दुष्ट प्रक्रिया सभी मेमोरी को खा सकती है चाहे कोई कितना भी स्थापित किया हो, और एक स्वैपिंग के बिना भी थ्रैशिंग-समस्याओं में आ सकता है जब बफरिंग / कैशिंग के लिए पर्याप्त मेमोरी नहीं है)। मैं थ्रैश-प्रोटेक्शन और बहुत सारे स्वैप स्पेस की सलाह देता हूं।


के अनुसार स्वैप को अक्षम करने के बारे में unix.stackexchange.com/a/24646/9108 यह सबसे अच्छा विकल्प नहीं हो सकता है।
sashoalm

दरअसल, किसी ने मुझ पर एक ही टिप्पणी की, इसलिए मैंने उस बिंदु पर थ्रैश-प्रोटेक्ट डॉक को संशोधित किया है।
tobixen

3
  1. अत्यधिक स्वैपिंग के कारण गैर-जिम्मेदार या बेहद सुस्त हो चुके लिनक्स सिस्टम पर नियंत्रण पाने का सबसे तेज़ तरीका क्या है?

पहले से ही साथ जवाब दिया Alt-SysRq-एफ

  1. क्या इस तरह की अदला-बदली को रोकने के लिए एक प्रभावी तरीका है, उदाहरण के लिए, स्मृति की मात्रा को सीमित करके एक प्रक्रिया को आवंटित करने की कोशिश करने की अनुमति है?

मैं इस 2 भाग का जवाब दे रहा हूं। हाँ, ulimit अभी भी एक ही प्रक्रिया को सीमित करने के लिए पर्याप्त रूप से काम करता है। आप ऐसा कर सकते हैं:

  • एक प्रक्रिया के लिए एक नरम सीमा निर्धारित करें जिसे आप जानते हैं कि वह नियंत्रण से बाहर हो जाएगी
  • यदि आप अतिरिक्त बीमा चाहते हैं तो सभी प्रक्रियाओं के लिए एक कठिन सीमा निर्धारित करें

जैसा कि, संक्षेप में बताया गया है:

आप संसाधन उपयोग को सीमित करने और ऐसी समस्याओं को रोकने के लिए सीजीग्रुप का उपयोग कर सकते हैं

वास्तव में, cgroups अधिक उन्नत नियंत्रण प्रदान करते हैं, लेकिन वर्तमान में मेरी राय में कॉन्फ़िगर करने के लिए अधिक जटिल हैं।

पुराना स्कूल अलिमित

एक बार बंद

एक सरल उदाहरण है:

$ bash
$ ulimit -S -v $((1*2**20))
$ r2(){r2 $@$@;};r2 r2
bash: xmalloc: .././subst.c:3550: cannot allocate 134217729 bytes (946343936 bytes allocated)

यह:

  • 1GB समग्र मेमोरी उपयोग की नरम सीमा निर्धारित करता है (kB इकाई में सीमा सीमित करता है)
  • एक पुनरावर्ती बैश फ़ंक्शन कॉल चलाता है r2(){ r2 $@$@;};r2 r2 स्टैक मेमोरी को रिक्वेस्ट करते हुए CPU और RAM को तेजी से दोगुना करते हुए तेजी से चबाता है।

जैसा कि आप देख सकते हैं, 1GB से अधिक अनुरोध करने की कोशिश करने पर यह बंद हो गया।

ध्यान दें, -v वर्चुअल मेमोरी एलोकेशन (कुल, यानी फिजिकल + स्वैप) पर काम करता है।

स्थायी सुरक्षा

वर्चुअल मेमोरी आवंटन को सीमित करने के लिए, as के बराबर है -v के लिये limits.conf

मैं किसी भी दुर्व्यवहार प्रक्रिया से बचाने के लिए निम्नलिखित कार्य करता हूं:

  • सभी प्रक्रियाओं के लिए एक हार्ड एड्रेस स्पेस लिमिट सेट करें।
  • address space limit = <physical memory> - 256MB
  • इसलिए, लालची मेमोरी उपयोग या एक सक्रिय लूप और मेमोरी लीक के साथ कोई भी एकल प्रक्रिया सभी भौतिक मेमोरी का उपभोग नहीं कर सकती है।
  • 256MB हेडरूम ssh या कंसोल के साथ आवश्यक प्रसंस्करण के लिए है।

एक लाइन:

$ sudo bash -c "echo -e \"*\thard\tas\t$(($(grep -E 'MemTotal' /proc/meminfo | grep -oP '(?<=\s)\d+(?=\skB$)') - 256*2**10))\" > /etc/security/limits.d/mem.conf"

मान्य करने के लिए, यह निम्नलिखित (जैसे 16GB सिस्टम पर) होता है:

$ cat /etc/security/limits.d/mem.conf
*   hard    as      16135196
$ ulimit -H -v
161351960

टिप्पणियाँ:

  • मेमोरी उपयोग के साथ ओवरबोर्ड जाने वाली एकल प्रक्रिया के खिलाफ केवल मिती
  • भारी मेमोरी दबाव के साथ एक बहु-प्रक्रिया कार्यभार को नहीं रोकेंगे, जिसके कारण थ्रशिंग (जवाब तब होता है)
  • उपयोग न करें rss सीमा में विकल्प ।conf। यह नई गुठली द्वारा सम्मानित नहीं है।
  • यह रूढ़िवादी है।
    • सिद्धांत रूप में, एक प्रक्रिया सट्टा रूप से बहुत सारी मेमोरी का अनुरोध कर सकती है लेकिन केवल सक्रिय रूप से एक सबसेट (छोटे कामकाजी सेट / निवासी मेमोरी उपयोग) का उपयोग करें।
    • उपरोक्त कठिन सीमा के कारण ऐसी प्रक्रियाएं निरस्त हो जाएंगी (भले ही वे ठीक से चलाए गए लिनक्स को भी याद कर सकें, वर्चुअल मेमोरी एड्रेस स्पेस को ओवरकम्यूज किया जा सकता है)।

नए सीजी समूह

अधिक नियंत्रण प्रदान करता है, लेकिन वर्तमान में उपयोग करने के लिए अधिक जटिल है:

  • Ulimit की पेशकश पर सुधार।
    • memory.max_usage_in_bytes खाते और भौतिक स्मृति को अलग से सीमित कर सकते हैं।
    • जहाँ तक ulimit -m और / या rss में limits.conf इसी तरह की कार्यक्षमता की पेशकश करने के लिए था, लेकिन यह कर्नेल लिनक्स 2.4.30 से काम नहीं करता है
  • बूटलोडर में कुछ कर्नेल cgroup ध्वज सक्षम करने की आवश्यकता है: cgroup_enable=memory swapaccount=1
    • यह Ubuntu 16.04 के साथ डिफ़ॉल्ट रूप से नहीं हुआ।
    • संभवतः अतिरिक्त लेखांकन ओवरहेड के कुछ प्रदर्शन निहितार्थों के कारण।
  • cgroup / systemd सामान अपेक्षाकृत नया है और एक उचित बिट को बदल रहा है, इसलिए फ्लक्स अपस्ट्रीम का अर्थ लिनक्स डिस्ट्रो विक्रेताओं ने अभी तक इसका उपयोग करना आसान नहीं बनाया है। 14.04LTS और 16.04LTS के बीच, cgroups का उपयोग करने के लिए उपयोगकर्ता का स्थान बदल गया है।
    • cgm अब आधिकारिक तौर पर समर्थित यूजरस्पेस टूल लगता है।
    • सिस्टमड यूनिट फाइलें अभी तक ssh जैसी महत्वपूर्ण सेवाओं को प्राथमिकता देने के लिए किसी भी पूर्व-परिभाषित "वेंडर / डिस्ट्रो" डिफॉल्ट को नहीं लगती हैं।

जैसे वर्तमान सेटिंग्स की जांच करने के लिए:

$ echo $(($(cat /sys/fs/cgroup/memory/memory.max_usage_in_bytes) / 2**20)) MB
11389 MB
$ cat /sys/fs/cgroup/memory/memory.stat
...

जैसे किसी एकल प्रक्रिया की मेमोरी को सीमित करने के लिए:

$ cgm create memory mem_1G
$ cgm setvalue memory mem_1G memory.limit_in_bytes $((1*2**30))
$ cgm setvalue memory mem_1G memory.memsw.limit_in_bytes $((1*2**30))
$ bash
$ cgm movepid memory mem_1G $$
$ r2(){ r2 $@$@;};r2 r2
Killed

एक बैकग्राउंड प्रोसेस के रूप में रैम को चबाने की क्रिया में देखना और फिर मारना

$ bash -c 'cgm movepid memory mem_1G $$; r2(){ r2 $@$@;};r2 r2' & while [ -e /proc/$! ]; do ps -p $! -o pcpu,pmem,rss h; sleep 1; done
[1] 3201
 0.0  0.0  2876
 102  0.2 44056
 103  0.5 85024
 103  1.0 166944
 ...
98.9  5.6 920552
99.1  4.3 718196
[1]+  Killed                  bash -c 'cgm movepid memory mem_1G $$; r2(){ r2 $@$@;};r2 r2'

स्मृति अनुरोधों में घातांक (2 की शक्ति) नोट करें।

भविष्य में, आइए SSH और ग्राफ़िकल स्टैक जैसी महत्वपूर्ण चीज़ों के लिए "डिस्ट्रो / वेंडर्स" को पूर्व-कॉन्फ़िगर cgroup प्राथमिकताओं और सीमाओं (सिस्टमड इकाइयों के माध्यम से) में देखने की उम्मीद करें, जैसे कि वे कभी भी स्मृति से भूखे न हों।


2

आप दबा सकते हैं Ctrl - z कार्यक्रम को निलंबित करने के लिए। तब आप कर सकते हैं kill %1 (या जो भी नौकरी नंबर है या आप पीआईडी ​​का उपयोग कर सकते हैं)।

आप उपयोग कर सकते हैं ulimit एक प्रक्रिया के लिए उपलब्ध स्मृति की मात्रा को सीमित करने की कोशिश करने के लिए कमांड


Ctrl-Z अच्छा है, लेकिन आमतौर पर मैं एक Matlab GUI चला रहा हूं और कंट्रोलिंग टर्मिनल का ट्रैक खो चुका हूं, इसलिए Ctrl-Z कुंजी को जारी करने का कोई आसान तरीका नहीं है। यह अच्छा होगा यदि GUI के पास जो भी एप्लिकेशन फोकस है उसे SIGSTOP भेजने के लिए एक हॉट कुंजी है!
nibot

तुम दौड़ सकते हो kill -STOP <pid> जो Ctrl-Z की तरह ही काम करेगा।
hlovdal

हां, लेकिन पूरी समस्या यह है कि, ऐसी स्थिति में, सिस्टम इतना गैर-प्रतिक्रियाशील होता है कि कमांड प्रॉम्प्ट पर पहुंचने में लंबा समय (या हमेशा के लिए) लगता है।
nibot

1

संसाधन उपयोग को सीमित करने और इस तरह की समस्याओं को रोकने के लिए आप सीजीग्रुप का उपयोग कर सकते हैं: https://en.wikipedia.org/wiki/Cgroups


कृपया अपने उत्तर में आवश्यक जानकारी शामिल करें और लिंक का उपयोग केवल अटेंशन और आगे पढ़ने के लिए करें। यह लिंक वर्णन करता है कि सीजीग्रुप क्या है, लेकिन यह लिंक से स्पष्ट नहीं है कि समस्या को हल करने के लिए वास्तव में इसका उपयोग कैसे करें। क्या आप प्रश्न के समाधान का वर्णन करने के लिए अपने उत्तर का विस्तार कर सकते हैं? धन्यवाद।
fixer1234

0

यह अच्छा होगा यदि GUI के पास जो भी एप्लिकेशन फोकस है उसे SIGSTOP भेजने के लिए एक हॉट कुंजी है!

हमेशा शास्त्रीय होता है xkill आदेश (मेरे सिस्टम पर xorg-x11-apps-7.4-14.fc14.src.rpm से)। मुझे लगता है कि एक ऐसा क्लोन बनाना बहुत मुश्किल नहीं होना चाहिए जो लक्ष्य विंडो को मारने के बजाय SIGSTOP भेजता है।


मैं कुछ प्रमुख संयोजन के प्रेस पर जल्दी से xkill कैसे बना सकता हूं?
nibot

मुझे यकीन नहीं है। मुझे लगता है कि सूक्ति और केडीई दोनों में कुछ वैश्विक शॉर्टकट कार्यक्षमता है जिसका उपयोग प्रोग्राम लॉन्च करने के लिए किया जा सकता है।
hlovdal
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.