2010-09-24 12 views
5

मुझे एक समस्या है जो स्मृति मैपिंग और लिनक्स के तहत बढ़ती स्मृति खपत से संबंधित कई धागे में वर्णित है।लिनक्स मेमोरी मैप की गई फाइलें आरक्षित भौतिक मेमोरी

जब मैं लिनक्स या MacOS एक्स के तहत एक 1GB फ़ाइल को खोलने और का उपयोग कर

me.data_begin = mmap(NULL, capacity(me), prot, MAP_SHARED, me.file.handle, 0); 

और क्रमिक रूप से पढ़ने के लिए मैप किया स्मृति, मेरे कार्यक्रम में अधिक से अधिक भौतिक स्मृति हालांकि मैं posix_madvise इस्तेमाल किया उपयोग करता स्मृति में नक्शा (यहां तक ​​कि कहा जाता है इसे पढ़ने की प्रक्रिया के दौरान कई बार):

posix_madvise(me.data_begin, capacity(me), MMAP_SEQUENTIAL); 

सफलता के बिना। :-(

मैंने कोशिश की:

  • अलग झंडे MMAP_RANDOM, MMAP_DONTNEED, सफलता के बिना MMAP_NORMAL
  • posix_fadvise (me.file.handle, 0, क्षमता (मुझे), POSIX_FADV_DONTNEED) पहले और mmap बुला के बाद -> कोई सफलता

यह मैक ओएस एक्स के तहत !!! जब मैं गठबंधन

posix_madvise(.. MMAP_SEQUENTIAL) 
काम करता है

और

msync(me.data_begin, capacity(me), MS_INVALIDATE). 

निवासी स्मृति (मैं समय-समय पर 16mio चरणों के बाद msync कहा जाता है) 16M नीचे है।

लेकिन के तहत लिनक्स कुछ भी काम करता है। क्या किसी के पास लिनक्स के तहत मेरी समस्या के लिए कोई विचार या सफलता की कहानी है?

चीयर्स, डेविड

+0

यह प्रासंगिक हो सकता है या नहीं भी हो सकता है, लेकिन यह जानना उपयोगी होना चाहिए: क्या आप 32-बिट या 64-बिट सिस्टम का उपयोग कर रहे हैं? क्या आप जानते हैं कि आपको 32-बिट सिस्टम में 1 जीबी को एमएमएपी नहीं करना चाहिए? (भले ही आप 64-बिट सिस्टम का उपयोग कर रहे हों, आप पोर्टेबिलिटी के बारे में चिंतित हो सकते हैं)। – Juliano

+0

सभी सिस्टम 64 बिट (64 बिट फ़ाइल पॉइंटर्स और ऑफ़सेट के साथ) हैं और मैं सफलतापूर्वक 40 जीबी फाइलों को मैप कर सकता हूं। मैंने पुनरुत्पादन के लिए समस्या को 1 जीबी तक उबाल दिया। – Dave

+0

@ सेवन। ऐसे मामले हैं जब मेमोरी मैपिंग का उपयोग करना अपरिहार्य है, उदाहरण के लिए जब किसी लाइब्रेरी कॉल को फ़ाइल की बजाय मेमोरी क्षेत्र की आवश्यकता होती है। तो आपका सुझाव असहनीय है और सवाल का जवाब नहीं देता है। जवाब के रूप में, स्पष्ट रूप से लिनक्स MMAP_SEQUENTIAL पर बहुत अधिक * टूटा हुआ * है। पढ़ा गया आगे का हिस्सा काम करता है, पेज पुनः दावा करने वाला पृष्ठ नहीं है। और एकमात्र तरीका लिनक्स को सुझाव देता है कि वास्तव में ये पृष्ठ अच्छे उम्मीदवार हैं जो क्षेत्र को अनैप करके (और इसे दोबारा मैप कर रहे हैं)। –

उत्तर

8

लिनक्स स्मृति प्रबंधन अन्य प्रणालियों से अलग है। मुख्य सिद्धांत यह है कि स्मृति का उपयोग नहीं किया जा रहा है स्मृति स्मृति बर्बाद हो रही है। कई मायनों में, लिनक्स बेहतर प्रदर्शन में परिणामस्वरूप (अधिकांश समय) मेमोरी उपयोग को अधिकतम करने की कोशिश करता है।

यह नहीं है कि "लिनक्स में" कुछ भी काम नहीं करता है, लेकिन इसका व्यवहार अपेक्षा से थोड़ा अलग है।

जब स्मृति पृष्ठों को एमएमएपी फ़ाइल से खींचा जाता है, तो ऑपरेटिंग सिस्टम को यह तय करना होता है कि उपयोग करने के लिए कौन से भौतिक मेमोरी पेज रिलीज़ होंगे (या स्वैप आउट)। यह उन पृष्ठों की तलाश करेगा जो स्वैप करना आसान है (तत्काल डिस्क लिखने की आवश्यकता नहीं है) और फिर से उपयोग होने की संभावना कम है।

पागलवाइस() POSIX कॉल सिस्टम को यह बताने के लिए कार्य करता है कि आपका एप्लिकेशन पृष्ठों का उपयोग कैसे करेगा। लेकिन जैसा कि नाम कहता है, यह सलाह है ताकि ऑपरेटिंग सिस्टम पेजिंग और निर्णय लेने में बेहतर साधन हो। यह न तो नीति है और न ही एक आदेश है।

लिनक्स पर मैडवाइस() के प्रभावों का प्रदर्शन करने के लिए, मैंने अपने छात्रों को दिए गए अभ्यासों में से एक को संशोधित किया। complete source code here देखें। मेरा सिस्टम 64-बिट है और इसमें 2 जीबी रैम है, जो अब लगभग 50% उपयोग में है। 2 जीबी फ़ाइल को एमएमएपी करने के लिए प्रोग्राम का उपयोग करके, इसे अनुक्रमिक रूप से पढ़ें और सब कुछ छोड़ दें। यह आरएसएस उपयोग की रिपोर्ट करता है हर 200 एमबी पढ़ा जाता है।परिणाम madvice बिना():

<[email protected]> ~% ./madvtest file.dat n 
    0 :  3 MB 
    200 : 202 MB 
    400 : 402 MB 
    600 : 602 MB 
    800 : 802 MB 
    1000 : 1002 MB 
    1200 : 1066 MB 
    1400 : 1068 MB 
    1600 : 1078 MB 
    1800 : 1113 MB 
    2000 : 1113 MB 

लिनक्स के आसपास 1 जीबी तक मेमोरी खत्म बातें धक्का पढ़ा गया था रखा। इसके बाद, इसने प्रक्रिया को स्वयं दबाया (क्योंकि अन्य 50% स्मृति अन्य प्रक्रियाओं द्वारा सक्रिय थी) और फ़ाइल के अंत तक स्थिर हो गई।

अब, madvice साथ():

<[email protected]> ~% ./madvtest file.dat y 
    0 :  3 MB 
    200 : 202 MB 
    400 : 402 MB 
    600 : 494 MB 
    800 : 501 MB 
    1000 : 518 MB 
    1200 : 530 MB 
    1400 : 530 MB 
    1600 : 530 MB 
    1800 : 595 MB 
    2000 : 788 MB 

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

आप पूछ सकते हैं कि क्यों लिनक्स 500 एमबी तक पृष्ठों को आवंटित करता रहा और जल्द से जल्द नहीं रुक गया, क्योंकि उन्हें अनुक्रमिक पहुंच के रूप में चिह्नित किया गया था। यह है कि या तो सिस्टम के पास पर्याप्त फ्री मेमोरी पेज थे, या अन्य निवासी पृष्ठ चारों ओर रखने के लिए बहुत पुराने थे। प्राचीन पृष्ठों को स्मृति में रखने के बीच जो अब उपयोगी नहीं लग रहा है, और चला रहे प्रोग्राम को सेवा देने के लिए और अधिक पृष्ठ लाने के लिए, लिनक्स दूसरा विकल्प चुनता है।

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

+0

धन्यवाद जूलियानो, कि 50% व्यवहार दिलचस्प है। मुझे आश्चर्य है कि लिनक्स को उन पृष्ठों को मुक्त करने का कोई तरीका नहीं है जिन्हें मैंने कभी नहीं पढ़ा। इसके बजाय यह फाइल सिस्टम के बफर और कैश बलिदान करता है। मैकोज़ एक्स पर बफर इन बफर सिस्टम को तब तक स्टाल करता है जब तक कि यह पूरी तरह से अनुपयोगी न हो। लेकिन सौभाग्य से हम इसे * msync (... MS_INVALIDATE) * लिनक्स पर ऐसा लगता है कि आपने पागलपन के साथ देखा व्यवहार है जो सिस्टम को रोकने से रोकता है। – Dave

+1

@ डेव: मान लें कि उन पृष्ठों को समय-समय पर मुक्त करने का कोई मतलब नहीं है। लिनक्स कैश और बफर का त्याग नहीं कर रहा है, इसके बजाय, यह बिल्कुल ठीक कर रहा है। जैसे ही आप डिस्क से अधिक डेटा पढ़ते हैं, लिनक्स को इन्हें स्मृति में लाने के लिए है। यह कैश की तरह डिस्क से पढ़ा गया था, लेकिन इसे "कैश" के रूप में लेखित करने के बजाय, यह उस प्रक्रिया के आरएसएस के हिस्से के हिस्से के रूप में खाता है जिसने उस फ़ाइल को मैप किया था। जब लिनक्स को फिर से कैश की आवश्यकता होती है, तो वह उस पृष्ठ पर मैप किए गए उन पृष्ठों को मुक्त कर देगा। आपको इसके बारे में चिंतित होने की आवश्यकता नहीं है! – Juliano

+0

@ जुलिआनो: मान लें कि MADV_SEQUENTIAL विशेष रूप से सिस्टम को बताता है कि पृष्ठों को अनुक्रमिक-पढ़ने के माध्यम से केवल एक बार पढ़ने के लिए उपयोग किया जा रहा है। ये पृष्ठ पुनः दावा के लिए सही उम्मीदवार हैं।इसके बजाय, मैं देखता हूं कि मेरे बॉक्स पर, जब तक 50% मेमोरी (उस मामले में 32 जीबी) तक नहीं पहुंच जाती है, तो फ़ाइल कैश को पुनः दावा किया जा रहा है। और मुझे लगता है कि अन्य प्रक्रियाओं का प्रदर्शन घट रहा है, अब मुझे लिनक्स को ऐसा करने के लिए मजबूर करने का एक हास्यास्पद तरीका मिला है। फाइल को अनैपिंग और मैप करके, प्रत्येक 1 जीबी या तो। वह * करता है * समस्या हल करता है और इसके बाद मुझे अन्य प्रक्रियाओं के लिए प्रदर्शन अवक्रमण नहीं दिखता है। –

संबंधित मुद्दे