लिनक्स मेमोरी विखंडन


20

क्या लिनक्स पर मेमोरी विखंडन का पता लगाने का एक तरीका है? ऐसा इसलिए है क्योंकि कुछ लंबे समय से चल रहे सर्वरों पर मैंने प्रदर्शन में गिरावट देखी है और प्रक्रिया को फिर से शुरू करने के बाद ही मुझे बेहतर प्रदर्शन दिखाई देता है। लिनक्स के विशाल पृष्ठ समर्थन का उपयोग करते समय मैंने इसे और अधिक देखा - क्या लिनक्स में विशाल पृष्ठ विखंडन से अधिक प्रभावित हैं?

मैंने विशेष रूप से / proc / friendinfo को देखा है। मैं यह जानना चाहता हूं कि क्या कोई बेहतर तरीका है (न केवल सीएलआई कमांड प्रति एसई, कोई कार्यक्रम या सैद्धांतिक पृष्ठभूमि क्या करेगी) इसे देखने के लिए।


मैं सिर्फ त्वरित कमांडलाइन समाधान नहीं देख रहा हूं, कोई भी सरल कार्यक्रम / सिद्धांत भी करेगा। इसलिए, मैंने सर्वरफॉल्ट पर नहीं पूछा।
रघु

1
मैं यहाँ एक बिंदु नहीं समझता। जहां तक ​​मैं समझता हूं कि स्मृति विखंडन स्मृति की कमी और स्मृति आवंटन त्रुटियों के परिणामस्वरूप होना चाहिए। हालाँकि आप प्रदर्शन में गिरावट के बारे में पूछ रहे हैं। क्या ऐसा इसलिए है क्योंकि आपके पास डिस्क पर बहुत सारी मेमोरी स्वैप है? और यदि ऐसा है तो vmstatक्षेत्र में क्या दे so?

@skwllsp - मेरे उत्तर को अधिक विशिष्ट होने के लिए संपादित किया।
टिम पोस्ट

@Raghu - मैं अधिकांश सिस्टम एडमिनिस्ट्रेटर से यह उम्मीद नहीं करूंगा कि मेमोरी मैनेजमेंट को अलग तरीके से करने के लिए कर्नेल कोड को संशोधित किया जाए, हालांकि, कुशल लिनक्स व्यवस्थापक को कम से कम यह जानना चाहिए कि लिनक्स मेमोरी को कैसे प्रबंधित करता है। यह सवाल वास्तव में लाइन पर है। मैंने इसे केवल इसलिए स्थानांतरित करने के लिए मतदान किया क्योंकि मैं आपके प्रश्न का उत्तर देने वाले (मेरे उत्तर में) कोड का सुझाव नहीं दे सकता। / से पढ़ना या उपयोग vmstatकरना एक सामान्य उपयोगकर्ता अनुभव है। यदि आप ऐसा करने के लिए एक कार्यक्रम लिख रहे थे , तो यह अलग होगा। आप इस जानकारी फसल बैश का उपयोग करना चाहते हैं, अपने प्रश्न संपादित करें, इसे बंद कर दिया नहीं किया जाएगा :)
टिम पोस्ट

@ टिम - जैसा कि मैंने सुझाव दिया है कि यह सिर्फ बैश / सीएलआई कमांड नहीं है जिसे मैं जानना चाहता था, मुझे मेरी बेंचमार्किंग प्रक्रिया में मदद करने के लिए जानकारी की आवश्यकता थी (परिणामों का विश्लेषण करने के लिए, उन्हें चलाने के लिए नहीं)।
रघु

जवाबों:


12

मैं टैग का जवाब दे रहा हूं । मेरा जवाब केवल लिनक्स के लिए विशिष्ट है ।

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

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

लंबे समय तक चलने वाले सर्वरों पर आपके द्वारा अस्वीकृत प्रदर्शन को देखने का कारण सबसे अधिक संभावना है क्योंकि आवंटित ब्लॉक जिन्हें स्पष्ट रूप से लॉक नहीं किया गया है (उदाहरण के लिए mlock()/ mlockall()या posix_madvise()) और थोड़ी देर में संशोधित नहीं किया गया है , जिसका अर्थ है कि आपकी सेवा स्किड्स डिस्क पर है जब इसे पढ़ना होगा उन्हें। इस व्यवहार को संशोधित करने से आपकी प्रक्रिया खराब हो जाती है , यही वजह है कि बहुत से लोग अपने RDBMS को वेब / php / python / ruby ​​/ जो भी हो की तुलना में पूरी तरह से अलग सर्वर पर डालते हैं। इसे ठीक करने का एकमात्र तरीका, पवित्र रूप से, सन्निहित ब्लॉकों के लिए प्रतिस्पर्धा को कम करना है।

जब पृष्ठ A स्मृति में है और पृष्ठ B स्वैप करने के लिए स्थानांतरित हो गया है, तो विखंडन वास्तव में केवल ध्यान देने योग्य है (ज्यादातर मामलों में)। स्वाभाविक रूप से, आपकी सेवा को फिर से शुरू करने से यह 'ठीक' हो जाएगा, लेकिन केवल इसलिए कि कर्नेल को अभी तक इस प्रक्रिया को पृष्ठांकित करने का अवसर नहीं मिला है (अब) नए आवंटित किए गए ब्लॉकों को इसके ओवरकम के अनुपात के दायरे में रखा गया है।

वास्तव में, एक उच्च भार के तहत फिर से शुरू (कहने देता है) 'अपाचे' डिस्क को सीधे अन्य सेवाओं के स्वामित्व वाले ब्लॉक भेजने की संभावना है। तो, हाँ, 'अपाचे' थोड़े समय के लिए सुधर जाएगा, लेकिन 'mysql' पीड़ित हो सकता है .. कम से कम तब तक जब तक कर्नेल उन्हें समान रूप से पीड़ित नहीं करता है जब बस पर्याप्त भौतिक स्मृति की कमी होती है।

अधिक मेमोरी जोड़ें, या malloc()उपभोक्ताओं की मांग को विभाजित करें :) यह न केवल विखंडन है जिसे आपको देखने की आवश्यकता है।

vmstatवास्तव में जहाँ संग्रहीत किया जा रहा है उसका अवलोकन प्राप्त करने का प्रयास करें ।


जवाब के लिए धन्यवाद। मैं mysql - innodb बफर पूल के लिए विशाल पृष्ठों (आकार = 2048KB प्रत्येक) का उपयोग कर रहा था - यह देखने के लिए कि यह कितनी अच्छी तरह किराए पर है (sysbench का उपयोग करके)। प्रारंभ में जब प्रक्रिया अपटाइम (और यहां तक ​​कि सिस्टम अपटाइम) कम था, यह बहुत अच्छे परिणाम दे रहा था। हालाँकि, इसके प्रदर्शन ने कई रनों से अधिक गिरावट शुरू कर दी। आपके द्वारा बताए गए पेज के बारे में, मैंने निश्चित रूप से एक उच्च वीएम गतिविधि पर ध्यान दिया है, लेकिन मैंने माना कि बेंचमार्क और इनोडब लॉग लॉगिंग के कारण हो सकता है (वीएम गतिविधि बिना पेजों की तुलना में अधिक है)। मैंने vm.swappiness को भी 1 में सेट किया है। मैं किसी भी कठोर बदलाव को नोटिस नहीं कर सका।
रघु

ठीक मैनुअल के अनुसार , "विशाल पृष्ठों को स्मृति दबाव में स्वैप नहीं किया जा सकता है।" मुझे लगता है कि यह w / r / t मानक स्मृति में एक अच्छा उत्तर है, लेकिन विशालकाय के लिए नहीं।
दान प्रिट्स

5

गुठली

वर्तमान विखंडन सूचकांक का उपयोग करने के लिए:

sudo cat /sys/kernel/debug/extfrag/extfrag_index

कर्नेल मेमोरी को डीफ़्रैग्मेन्ट करने के लिए निष्पादित करने का प्रयास करें:

sysctl vm.compact_memory=1  

इसके अलावा, आप पारदर्शी विशाल पृष्ठ (उर्फ THP) और / या स्वैप (या कमी swappiness) को अक्षम करने का प्रयास करते हैं ।

उपयोक्ता स्थान

उपयोगकर्ताओं के विखंडन को कम करने के लिए आप अलग-अलग आवंटनकर्ता का प्रयास करना चाह सकते हैं, उदाहरण के लिए jemalloc(इसमें महान आत्मनिरीक्षण क्षमता है , जो आपको आंतरिक आंतरिक विखंडन में अंदर देगा)।

आप इसके साथ अपने प्रोग्राम को फिर से शुरू करके या इसके साथ अपना प्रोग्राम चलाकर कस्टम मॉलॉक में जा सकते हैं LD_PRELOAD: LD_PRELOAD=${JEMALLOC_PATH}/lib/libjemalloc.so.1 app ( THP और मेमोरी मेमोरी एलोकेटर्स के बीच बातचीत से सावधान )

हालाँकि, मेमोरी विखंडन से थोड़ा असंबंधित (लेकिन मेमोरी कंप्रेशन / माइग्रेशन से जुड़ा हुआ), आप शायद अपनी सेवा के कई उदाहरणों को चलाना चाहते हैं, प्रत्येक NUMA नोड के लिए और उन्हें उपयोग करके बाइंड करें numactl


1
आप क्यों सोचेंगे कि स्वैप को अक्षम करने से मदद मिल सकती है? मेरे लिए यह अधिक संभावना है कि स्वैप को अक्षम करने से और भी अधिक चोट पहुंचेगी।
कास्परड

1
क्योंकि मूल पोस्ट में पर्याप्त जानकारी नहीं है, हो सकता है कि प्रक्रिया अभी लीक हो रही है और स्वैपिंग शुरू हो। इसके अलावा, मैं किसी भी उत्पादन प्रणाली पर स्वैप का उपयोग करने के लिए कोई वैध कारण नहीं देखता हूं (केवल छात्रों के लिए साझा कार्यस्थानों के लिए एमबी)।
SaveTheRbtz

2
पर्याप्त स्वैप स्थान होने से प्रदर्शन में सुधार होगा। यदि आपके पास अपर्याप्त स्वैप स्थान है तो प्रदर्शन समस्याएं आपको स्वैप को सक्षम करने के लिए पर्याप्त हैं।
कास्परड

1
@SaveTheRbtz उत्पादन प्रणाली पर स्वैप का उपयोग करने का एक अच्छा कारण यह है कि यह प्रणाली को अधिक विकल्प देता है कि यह तभी उपयोग करेगा जब उसे लगता है कि वे लाभकारी हैं। इसके अलावा, यह उन संशोधित पृष्ठों को अनुमति देता है जिन्हें घंटों तक एक्सेस नहीं किया गया (और कभी एक्सेस नहीं किया जा सकता) को अनमोल भौतिक स्मृति से निकाल दिया जाता है। अंत में, यह सिस्टम को उन मामलों को पूरी तरह से संभालने की अनुमति देता है जहां उपयोग किए जाने की तुलना में बहुत अधिक मेमोरी आरक्षित है।
डेविड श्वार्ट्ज

2
"केवल अगर यह सोचता है कि वे लाभकारी हैं" - जो अतिरिक्त हेयुरिस्टिक जोड़ता है और सिस्टम को कम अनुमानित बनाता है। इसके अलावा पृष्ठ प्रतिस्थापन एल्गोरिदम (स्वैप और अनाम में प्रयुक्त mmap) को अलग-अलग कर्नेल (जैसे लिनक्स बनाम फ्रीबीएसडी) पर लागू किया जाता है , या यहां तक ​​कि एक ही ओएस के अलग-अलग संस्करण (2.6.32 बनाम 3.2 बनाम 3.10) .. "यह संशोधित पृष्ठों को अनुमति देता है []। ..] [...] भौतिक स्मृति से बेदखल होने के लिए - जो मेमोरी लीक को छिपाएगा। "उन मामलों को संभालें जहां मेमोरी की तुलना में बहुत अधिक मेमोरी का उपयोग किया जाता है" - धीमा सिस्टम डाउन सिस्टम की तुलना में खराब है, इसलिए "समझदार" संदिग्ध है।
SaveTheRbtz

4

विशाल पृष्ठों का उपयोग लिनक्स पर अतिरिक्त मेमोरी विखंडन का कारण नहीं होना चाहिए; विशाल पृष्ठों के लिए लिनक्स समर्थन केवल साझा मेमोरी (शमगेट या एमएमएपी के माध्यम से) के लिए है, और उपयोग किए जाने वाले किसी भी विशाल पृष्ठ को सिस्टम व्यवस्थापक द्वारा विशेष रूप से अनुरोध और प्रचारित किया जाना चाहिए। एक बार स्मृति में, उन्हें वहाँ पिन किया जाता है, और बाहर स्वैप नहीं किया जाता है। स्मृति के विखंडन की स्थिति में विशाल पृष्ठों में स्वैपिंग की चुनौती ठीक उसी प्रकार है कि वे मेमोरी में पिन किए जाते हैं (जब 2MB का विशाल पृष्ठ आवंटित करते हैं, तो कर्नेल को 512 सन्निहित मुक्त 4KB पृष्ठ खोजने होंगे, जो मौजूद भी नहीं हो सकते हैं)।

विशाल पृष्ठों पर लिनक्स प्रलेखन: http://lwn.net/Articles/375098/

एक ऐसी परिस्थिति होती है जहाँ मेमोरी फ़्रेग्मेंटेशन के कारण बड़े पेज एलोकेशन धीमा हो सकता है (लेकिन नहीं जहाँ बड़े पेज मेमोरी फ्रैगमेंटेशन का कारण बनते हैं), और यदि आपके सिस्टम को एप्लिकेशन द्वारा अनुरोध किए जाने पर विशाल पेजों के पूल को विकसित करने के लिए कॉन्फ़िगर किया गया है। यदि / proc / sys / vm / nr_overcommit_hugepages / proc / sys / vm / nr_hugepages से अधिक है, तो ऐसा हो सकता है।


वास्तव में - और इसे आम तौर पर प्रदर्शन में मदद करनी चाहिए क्योंकि यह टीएलबी मिसेस को रोक देगा (स्पष्टीकरण के लिए लिंक किए गए लेख देखें)।
दान प्रिट्स

0

वहाँ है /proc/buddyinfoजो बहुत उपयोगी है। यह एक अच्छा आउटपुट प्रारूप के साथ अधिक उपयोगी है, जैसे यह पायथन स्क्रिप्ट कर सकती है:

https://gist.github.com/labeneator/9574294

विशाल पृष्ठों के लिए आप 2097152 (2MiB) आकार या बड़े में कुछ मुफ्त टुकड़े चाहते हैं। पारदर्शी विशाल पृष्ठों के लिए जब कर्नेल को कुछ के लिए कहा जाता है तो यह स्वचालित रूप से कॉम्पैक्ट हो जाएगा, लेकिन यदि आप यह देखना चाहते हैं कि आप कितने प्राप्त कर सकते हैं, तो रूट रन:

echo 1 | sudo tee /proc/sys/vm/compact_memory

इसके अलावा, विशाल पृष्ठ विखंडन के लिए बड़ी समस्याएं पैदा करते हैं। या तो आप कोई विशाल पृष्ठ प्राप्त नहीं कर सकते हैं, या उनकी उपस्थिति कर्नेल को कुछ अतिरिक्त समय बिताने की कोशिश कर रही है।

मेरे पास एक समाधान है जो मेरे लिए काम करता है। मैं इसे कुछ सर्वरों और अपने लैपटॉप पर उपयोग करता हूं। यह वर्चुअल मशीनों के लिए बहुत अच्छा काम करता है।

kernelcore=4Gअपने लिनक्स कर्नेल कमांड लाइन में विकल्प जोड़ें । अपने सर्वर पर मैं 8G का उपयोग करता हूं। संख्या से सावधान रहें, क्योंकि यह आपके कर्नेल को उस मेमोरी के बाहर कुछ भी आवंटित करने से रोक देगा। ऐसे सर्वर जिन्हें सॉकेट बफ़र्स की बहुत आवश्यकता होती है या जो स्ट्रीम डिस्क सैकड़ों ड्राइव पर लिखता है, इस तरह से सीमित होना पसंद नहीं करेगा। कोई स्मृति आवंटन जिसे स्लैब या डीएमए के लिए "पिन किया जाना" है, वह इस श्रेणी में है।

आपकी सभी अन्य मेमोरी तब "मूवेबल" हो जाती है, जिसका अर्थ है कि इसे विशाल पृष्ठ आवंटन के लिए अच्छी मात्रा में तैयार किया जा सकता है। अब पारदर्शी विशाल पृष्ठ वास्तव में बंद हो सकते हैं और काम कर सकते हैं जैसा कि उन्हें माना जाता है। जब भी कर्नेल को अधिक से अधिक 2M पृष्ठों की आवश्यकता होती है तो यह केवल 4K पृष्ठों को कहीं और रीमैप कर सकता है।

और, मुझे पूरी तरह से यकीन नहीं है कि यह शून्य-प्रतिलिपि प्रत्यक्ष IO के साथ कैसे इंटरैक्ट करता है। "जंगम ज़ोन" में मेमोरी को पिन नहीं किया जाना चाहिए, लेकिन एक प्रत्यक्ष IO अनुरोध DMA के लिए बिल्कुल ऐसा ही करेगा। इसे कॉपी कर सकते हैं। यह चल क्षेत्र में इसे वैसे भी पिन कर सकता है। किसी भी मामले में यह संभवतः वैसा नहीं है जैसा आप चाहते थे।

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