2010-12-01 12 views
8

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

मैं सिर्फ डेटा है कि अपने आवेदन नहीं रह गया है भौतिक स्मृति कब्जे या (संसाधन किसी भी तरह से बर्बाद कर) डिस्क के लिए बदली होने से उपयोग कर रहा है को रोकने के लिए चाहते हैं, मैं गिरी है कि यह अनावश्यक है, या mmap नया शून्य पृष्ठों पर madvise कर सकते हैं इसके ऊपर लेकिन इन दृष्टिकोणों में से कोई भी आवश्यक रूप से स्मृति की मात्रा को कम नहीं करेगा, जो कि अन्य प्रक्रियाओं को तब उपयोग करने से रोका जाता है।

क्या होगा यदि मैं पृष्ठों को ताजा शून्य पृष्ठों के साथ प्रतिस्थापित करता हूं जिन्हें केवल पढ़ने के लिए चिह्नित किया जाता है? मेरा इरादा यह है कि वे प्रतिबद्ध स्मृति की ओर गिनती नहीं करते हैं, और आगे मैं mprotect का उपयोग उन्हें लिखने के लिए कर सकता हूं, और अगर वे लिखने योग्य हो तो यह असफल हो जाएगा प्रतिबद्ध प्रतिबद्धता सीमा पर जायेगा। क्या मेरी समझ सही है? यह काम करेगा?

+1

एक पठनीय पृष्ठ को किसी प्रक्रिया में प्रतिबद्ध नहीं किया जाना चाहिए 'प्रतिबद्ध शुल्क (मेरे पास कोई संदर्भ नहीं है, इसलिए यह कोई जवाब नहीं है), और लिनक्स MAP_NORESERVE ध्वज प्रदान करता है जो आपको एक मजबूत भी प्रदान करना चाहिए गारंटी। लेकिन मुझे यह पूछना है: आप स्मृति में आरक्षित करने की आवश्यकता क्यों महसूस करते हैं जो उपयोग में नहीं है? – Anon

+0

खराब चीजें (टीएम) तब होती हैं जब समान वर्चुअल पतों को 'एमएमएपी' (यादृच्छिक रूप से) द्वारा आवंटित किया जाता है, बिना कार्यक्रम के जागरूक किए जाते हैं। :-) 'MAP_NORESERVE' के लिए, मुझे चिंता है कि पृष्ठों को बाद में लिखने के बाद भी पृष्ठों को गिनने से रोक सकता है। मुझे लगता है कि मैं फिर से नए शून्य पृष्ठों के साथ 'mmap'- पर फिर से कर सकता था। –

+0

क्या बुरी चीजें होती हैं? आपके प्रोग्राम को पहले कभी इस्तेमाल किए गए पता स्थान का पुन: उपयोग करने की आवश्यकता क्यों नहीं है? यह बहुत असामान्य लगता है। – Angus

उत्तर

1

यदि आप पृष्ठ का उपयोग नहीं कर रहे हैं (इसे पढ़ना या लिखना), तो यह आपके पता स्थान (केवल आरक्षित) में नहीं किया जाएगा।

लेकिन आपका पता स्थान सीमित है, इसलिए आप इसे जितना चाहें उतना नहीं खेल सकते हैं।

उदाहरण के लिए देखें इलेक्ट्रिकफ़ेंस जो "नूल पेज/गार्ड पेज" (बिना पहुंच के अज्ञात मेमोरी) को सम्मिलित करने के कारण बड़ी संख्या में आवंटन के लिए असफल हो सकता है। "Mprotect() विफल: स्मृति को आबंटित नहीं किया जा सकता": इन धागा पर एक नज़र डालें http://thread.gmane.org/gmane.comp.lib.glibc.user/538/focus=976052

+3

यह * वर्चुअल आकार से लिया जाएगा, लेकिन आरएसएस के लिए नहीं। –

1

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

ध्यान दें कि शून्य पृष्ठों के लिए लिनक्स का व्यवहार अतीत में बदल गया है; कुछ कर्नेल संस्करणों के साथ, बस पृष्ठ को पढ़ने से इसे आवंटित किया जाएगा। दूसरों के साथ, एक लेखन आवश्यक है। ध्यान दें कि सुरक्षा झंडे सीधे आवंटन का कारण नहीं बनते हैं; हालांकि वे आपको गलती से आवंटन को ट्रिगर करने से रोक सकते हैं। इसलिए, सबसे विश्वसनीय परिणामों के लिए आपको आईएनजी PROT_NONE के साथ पेज तक पहुंचने से बचना चाहिए।

एक और, अधिक पोर्टेबल विकल्प के रूप में, आप एक ही पृष्ठ पर कई स्थानों पर मानचित्र कर सकते हैं। यही है, एक खाली अस्थायी फ़ाइल बनाएं और खोलें, इसे अनलिंक करें, ftruncate पृष्ठों की कुछ उचित संख्या में, mmap बार-बार फ़ाइल में ऑफ़सेट 0 पर। यह पूरी तरह से स्मृति की गारंटी देगा कि आपके प्रोग्राम के मेमोरी उपयोग के विरुद्ध केवल एक बार गिना जाता है। जब आप पेज पर लिखते हैं तो आप MAP_PRIVATE का ऑटो-रीयलोकेट करने के लिए भी उपयोग कर सकते हैं।

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

+1

कुल मिलाकर उपयोगी जानकारी, लेकिन 'MAP_NORESERVE' उपयोगी नहीं है। यह अनदेखा किया जाता है जब ओवरकमिट पूरी तरह अक्षम हो जाता है। –

+0

क्या आपको लगता है कि मैपिंग '/ dev/zero' आपके प्रस्ताव में एक अस्थायी फ़ाइल के साथ-साथ काम करेगा? –

+0

@Zan, नहीं। '/ dev/zero' नक्शे सामान्य 'MAP_ANON' मानचित्र के समान हैं और इसलिए किसी भी अन्य स्मृति आवंटन के लिए जिम्मेदार ठहराया जाएगा। – bdonlan