RAM / OOM विफलता को परिभाषित करना


11

यह प्रश्न काफी लंबा है, इसलिए मैं शीर्ष पर प्रश्न पूछूंगा और फिर प्रश्नों पर आने की मेरी विधि के माध्यम से जाऊंगा:

  1. क्या (बिजीबॉक्स आधारित) rm निष्पादित नहीं हुआ क्योंकि पर्याप्त सन्निहित रैम नहीं था?
  2. यदि हां, तो क्या डीएमए को डीफ़्रैग्मेट करने का एक हल्का तरीका है - सिस्टम रीस्टार्ट का सहारा लिए बिना?
  3. यदि नहीं, तो इसका क्या कारण है? मैं इसे भविष्य में होने से कैसे रोक सकता हूं?

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

इसके बाद, मैंने अपने शेल कमांड के अधिक से अधिक ध्यान दिया और उम्मीद के मुताबिक प्रदर्शन नहीं किया।

मैं सही से निष्पादित करने में विफल होने के बाद dmesg से एक आउटपुट के साथ शुरू करूँगा :

प्रक्रिया 6821 (आरएम) से लंबाई 61440 का आवंटन विफल रहा

डीएमए प्रति-सीपीयू:

CPU 0: hi: 0, btch: 1 usd: 0

एक्टिव_नॉन: 0 सक्रिय_फाइल: 1 निष्क्रिय_ऑन: 0 निष्क्रिय_फाइल: 0 अपरिहार्य: 6 गंदा: 0 लेखन: 0 अस्थिर: 0 मुक्त: 821 स्लैब: 353 मैप किए गए: 0 पेजेबल्स: 0 उछाल: 0

डीएमए मुक्त: 3284kB मिनट: 360kB कम: 448kB उच्च: 540kB सक्रिय_नोन: 0kB निष्क्रिय_करण: 0kB सक्रिय_फाइल: 4kB निष्क्रिय_फाइल: 0kB निष्क्रिय: 24kB वर्तमान: 8128kB Pages_scanned: 0 all_unreclaimable नहीं

lowmem_reserve []: ० ० ०

डीएमए: 31 * 4kB 47 * 8kB 42 * 16kB 64 * 32kB 1 * 64kB 0 * 128kB 0 * 256kB 0 * 512kB 0 * 1024kB 0 * 2048kB 0 * 4096kB = 3284kB

14 कुल पृष्ठ पृष्ठ

प्रक्रिया डेटा के लिए रैम आवंटित करने में असमर्थ, 12 तक गलत नहीं है

प्रारंभ में, मुझे लगा कि मैं सन्निहित स्मृति के सबसे बड़े हिस्से में कार्यक्रम चलाने में असमर्थ था। मतलब डीएमए बहुत अधिक खंडित था और मुझे मेमोरी को डीफ़्रैग्मेन्ट करने के लिए सिस्टम प्राप्त करने का एक तरीका खोजना होगा।

फिर मैंने एक त्वरित गणित / पवित्रता जांच की और महसूस किया कि कार्यक्रम को एकमात्र 64kB सन्निहित मेमोरी स्लॉट में चलाने में सक्षम होना चाहिए। आरएम 61440 बाइट्स (60kB) का अनुरोध कर रहा था।

मैंने एक अच्छा पुराना "मैनुअल डिफ्रैग" किया और सिस्टम को रिबूट किया। जब मैंने sytem I को रिबूट किया / आउटपुट / procinfo:

Node 0, zone DMA 2 8 3 12 0 1 0 1 0 1 0

जिस पर मुझे शक है:

  • 2 x 4 केबी
  • 8 x 8 केबी
  • 3 x 16 kB
  • 12 x 32 kB
  • 1 एक्स 128 केबी
  • 1 एक्स 512 केबी

लेकिन अगर कोई उपरोक्त मानों की सूची पर हस्ताक्षर करता है, तो यह / proc / meminfo के आउटपुट के साथ मेल नहीं खाता है :

MemTotal:           6580 kB
MemFree:            3164 kB
Buffers:               0 kB
Cached:              728 kB
SwapCached:            0 kB
Active:              176 kB
Inactive:            524 kB
Active(anon):          0 kB
Inactive(anon):        0 kB
Active(file):        176 kB
Inactive(file):      524 kB`
Unevictable:           0 kB
Mlocked:               0 kB
MmapCopy:            844 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                 0 kB
Writeback:             0 kB
AnonPages:             0 kB
Mapped:                0 kB
Slab:               1268 kB
SReclaimable:        196 kB
SUnreclaim:         1072 kB
PageTables:            0 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:        3288 kB
Committed_AS:          0 kB
VmallocTotal:          0 kB
VmallocUsed:           0 kB
VmallocChunk:          0 kB

पुनरावृत्ति करने के लिए, मेरे प्रश्न हैं:

  1. क्या rm ने निष्पादित नहीं किया क्योंकि पर्याप्त सन्निहित रैम नहीं थी?
  2. यदि हां, तो क्या डीएमए को डीफ़्रैग्मेट करने का एक हल्का तरीका है - सिस्टम रीस्टार्ट का सहारा लिए बिना?
  3. यदि नहीं, तो इसका क्या कारण है? मैं इसे भविष्य में होने से कैसे रोक सकता हूं?

मैं Lantronix के XPort Pro (8MB, Linux OS) का उपयोग कर रहा हूं जो कि uClinux संस्करण 2.6.30 चला रहा है। उपयोग में शेल हश है।


माइनर पॉइंट: आपने मेमोरी चंक्स की अपनी सूची से 1 x 2048 kB छोड़ दिया। यदि आप इसे शामिल करते हैं, तो योग 3192 kB है, जो / proc / meminfo में सूचीबद्ध 3164 kB के बहुत करीब है।
एलेक्स सेलबी

जवाबों:


11

आपके प्रश्न 2 पर (स्मृति को डीफ़्रेग्मेंट करना), https://www.kernel.org/doc/Documentation/sysctl/vm.txt से उद्धृत करना :

compact_memory

CONFIG_COMPACTION सेट होने पर ही उपलब्ध है। जब 1 को फ़ाइल में लिखा जाता है, तो सभी ज़ोन को ऐसे कंपैक्ट किया जाता है कि जहाँ संभव हो वहाँ मुफ़्त मेमोरी उपलब्ध है। यह विशाल पृष्ठों के आवंटन में उदाहरण के लिए महत्वपूर्ण हो सकता है, हालांकि प्रक्रियाओं को आवश्यक रूप से सीधे कॉम्पैक्ट मेमोरी भी होगी।

इसका तात्पर्य यह है कि निम्नलिखित कमांड (रूट विशेषाधिकारों के साथ निष्पादित की जाती है और यदि ऊपर उल्लिखित कर्नेल विकल्प सक्षम था)

echo 1 > /proc/sys/vm/compact_memory

जितना संभव हो सके मेमोरी को डीफ़्रैग्मेन्ट करने का प्रयास करने के लिए कर्नेल को बताना चाहिए। खबर है कि कुछ RHEL6 संस्करणों पर जैसे, यह कर्नेल को दुर्घटनाग्रस्त कर सकता है ...


1
एक पुराने प्रश्न पर वापस आने और टिप्पणी करने के लिए समय बिताने के लिए धन्यवाद!
OldTinfoil

7

इसमें थोड़ा समय लगा है, लेकिन मुझे लगा कि जब तक मेरे सभी उप-प्रश्नों के उत्तर नहीं होंगे, तब तक मैं उत्तर देना बंद कर दूंगा।

इससे पहले कि मैं शुरू करूं, मैं यह उल्लेख करूंगा कि "डी-टुकड़ाकरण" काम करने वाली मेमोरी की सही अवधि "वर्किंग मेमोरी" "मेमोरी" कहलाती है।

1. क्या rm निष्पादित नहीं किया गया था क्योंकि पर्याप्त सन्निहित रैम नहीं था?

मैं अपने निष्कर्ष में सही था - आरएम निष्पादित नहीं किया गया था क्योंकि अपर्याप्त सन्निहित रैम था। सिस्टम रैम प्राप्त कर रहा था और इसे खंडित कर रहा था, इस प्रकार यह अप्राप्य बना।

2. यदि हां, तो क्या डीएमए को डीफ़्रैग्मेट करने का एक हल्का तरीका है - सिस्टम रीस्टार्ट का सहारा लिए बिना?

बाहर मुड़ता है स्मृति को संकुचित करने का कोई तरीका नहीं है, एम्बेडेड सिस्टम को फिर से शुरू करने की कमी है। MMU- कम प्रणाली के मामले में, रोकथाम खेल का नाम है।

अगर सॉफ्टवेयर में MMU का अनुकरण करने के लिए लिनक्स कर्नेल को हैक करना संभव हो तो मुझे इसका एक हिस्सा आश्चर्यचकित करता है। मुझे लगता है कि अगर यह संभव था, तो किसी ने पहले ही कर दिया होता। मैं इसकी पूरी तरह से नई अवधारणा की कल्पना नहीं कर सकता;)

3. मैं इसे भविष्य में होने से कैसे रोक सकता हूं?

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

परियोजना के पहले पुनरावृत्ति पर, हमने महत्वपूर्ण कार्य करने के लिए मेरी शेल स्क्रिप्ट कॉल पर भरोसा किया (जैसे rm)। यदि हमें आवश्यकता नहीं थी तो हमें पहिये का फिर से आविष्कार करने की आवश्यकता नहीं थी।

हालाँकि, मैं सुझाव दूंगा कि शेल को MMU- कम प्रणाली के लिए जहाँ संभव हो -

( प्रश्न , यदि आप निष्पादित करते हैं तो क्या होता है ls -la /path/to/directory/ | grep file-i-seek?)

( उत्तर : यह एक नया उपप्रकार शुरू करता है)

यदि आपको अपने सी प्रोग्राम में कुछ मुख्य शेल स्क्रिप्ट कार्यक्षमता को लागू करने की आवश्यकता है, तो मैं बिजीबॉक्स में उपयोग किए गए स्रोत कोड की जांच करने की सलाह देता हूं । संभावना है कि आप अपने एम्बेडेड सिस्टम में C का उपयोग कर रहे हैं ..


वापस आने और अपना निष्कर्ष साझा करने के लिए समय निकालने के लिए धन्यवाद।
कालेब

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

उस प्रतिक्रिया को लिखने के लिए वापस आने और समय बिताने के लिए धन्यवाद। नहीं पता था कि macOS क्लासिक ने ऐसा किया।
ओल्डटिनफिल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.