operating system कहाँ एकाधिक ढेर और ढेर आभासी स्मृति में डाल रहे हैं?




operating-system stack (2)

सीधे शब्दों में कहें, क्योंकि आपके सिस्टम संसाधन हमेशा सीमित होते हैं, आप असीम नहीं जा सकते।

मेमोरी प्रबंधन में हमेशा कई परतों होते हैं जिनमें प्रत्येक की अच्छी तरह से परिभाषित जिम्मेदारी होती है कार्यक्रम के परिप्रेक्ष्य से, एप्लिकेशन-स्तरीय प्रबंधक दिखाई देता है जो आमतौर पर केवल एक ही आवंटित ढेर के साथ ही चिंतित होता है। उपरोक्त एक स्तर (एक) अपने वैश्विक ग्लोबल ढेर के जरिए कई ढेर के निर्माण से निपट सकता है और उन्हें उपप्रोग्राम (प्रत्येक अपने स्वयं के मेमोरी मैनेजर के साथ) में निर्दिष्ट कर सकता है। इसके ऊपर मानक malloc() / free() हो सकता है जो कि उन पृष्ठों से संबंधित ऑपरेटिंग सिस्टम का उपयोग करता है और वास्तविक स्मृति आवंटन प्रति प्रक्रिया (यह मूल रूप से केवल कई ढेर के बारे में ही नहीं है, बल्कि उपयोगकर्ता के स्तर के ढेर में भी है सामान्य)।

मेमोरी प्रबंधन महंगा है और ऐसा कर्नेल में फँस गया है। दोनों के संयोजन में गंभीर प्रदर्शन हिट लगाया जा सकता है, इसलिए आवेदन के दृष्टिकोण से वास्तविक ढेर प्रबंधन को वास्तव में उपयोगकर्ता के स्थान (सी रनटाइम लाइब्रेरी) में कार्यान्वित करने के लिए कार्यान्वित किया जाता है (और अब के लिए अन्य कारण )।

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

दिन के अंत में, आपको ढेर और ढेर के लिए सीमाएं लगाने की आवश्यकता होगी ताकि वे अतिप्रवाह होने की संभावना न रखें, लेकिन आप दूसरों को आवंटित कर सकते हैं अगर किसी को उस सीमा से परे जाना चाहिए, तो आप या तो

  • त्रुटि के साथ आवेदन को समाप्त करें
  • स्मृति प्रबंधक को उस स्टैक / ढेर के लिए स्मृति ब्लॉक आवंटित / पुन: आकार / स्थानांतरित करें और सबसे अधिक बाद में ढेर (अपने स्वयं के स्तर) को डीफ्रैग्ज करना; यही कारण है कि free() आमतौर पर खराब प्रदर्शन करता है

प्रत्येक call पर एक बहुत बड़ी, 1 केबी स्टैक फ्रेम को ध्यान में रखते हुए (यदि डेवलपर का अनुभव नहीं है तो हो सकता है) 10 एमबी स्टैक 10240 नेस्टेड call -एस के लिए पर्याप्त होगा बीटीडब्लू, इसके अलावा, एक से अधिक स्टैक और ढेर प्रति धागा के लिए बहुत ज्यादा जरूरत नहीं है।

मैं एक कर्नल लिख रहा हूं और कई स्टैक और ढेर को वर्चुअल मेमोरी में रखने के लिए (और चाहते हैं) की जरूरत है, लेकिन मुझे यह समझ नहीं आ रहा है कि उन्हें कुशलतापूर्वक कैसे रखें। सामान्य कार्यक्रम कैसे करते हैं?

32-बिट सिस्टम द्वारा प्रदान की जाने वाली सीमित आभासी स्मृति में ढेर और ढेर कैसे (या कहां) होते हैं, जैसे कि उनके पास यथासंभव अधिक बढ़ती हुई जगह है?

उदाहरण के लिए, जब एक तुच्छ कार्यक्रम स्मृति में लोड होता है, तो उसके पता स्थान का लेआउट इस तरह दिख सकता है:

[  Code  Data  BSS  Heap->  ...  <-Stack  ]

इस मामले में ढेर के रूप में बड़ा हो सकता है क्योंकि वर्चुअल मेमोरी (जैसे स्टैक तक) की अनुमति देता है, और मेरा मानना ​​है कि यह सबसे अधिक कार्यक्रमों के लिए ढेर कैसे काम करता है कोई पूर्वनिर्धारित उच्च बाध्य नहीं है

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

मैं यह नहीं देखता हूं कि यह सभी ढेरों और ढेर के आकार पर पूर्वनिर्धारित सीमा के बिना, काफी कुशलतापूर्वक किया जाता है।


मुझे लगता है कि आपके कर्नेल में मूलभूत बातें हैं, पृष्ठ दोषों के लिए एक जाल हैंडलर जो कि रैम को वर्चुअल मेमोरी पेज को मैप कर सकते हैं। अगले स्तर ऊपर, आपको एक वर्चुअल मेमोरी एड्रेस स्पेस मैनेजर की ज़रूरत है जिससे सेयुरमोड कोड एड्रेस स्पेस का अनुरोध कर सकता है। एक सेगमेंट ग्रॅन्युलैरिटी चुनें जो अत्यधिक विखंडन को रोकता है, 64 केबी (16 पृष्ठ) एक अच्छी संख्या है। यूएसआरओडीए कोड को रिज़र्व स्पेस और कमिट स्पेस दोनों को अनुमति दें। खंड का ट्रैक रखने के लिए 4GB / 64KB = 64K x 2 बिट का एक साधारण बिटमैप काम किया जाता है। पेज फॉल्ट ट्रैप हेन्डलर को इस बिटमैप से यह जानने की भी जरूरत है कि क्या पृष्ठ अनुरोध मान्य है या नहीं।

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

हेप प्रबंधक का सबसे महत्वपूर्ण काम विखंडन को रोकने के लिए है। ऐसा करने का सबसे अच्छा तरीका है एक लुकसाइड सूची बनाने के लिए जो कि विभाजन के अनुरोध को आकार से ढेर कर देते हैं। 8 बाइट्स से कम सब कुछ सेगमेंट की पहली सूची से आता है। दूसरे से 8 से 16, तीसरे से 16 से 32, वगैरह आकार की बकेट को बढ़ाना, जैसा कि आप ऊपर जाते हैं। आपको सबसे अच्छा संतुलन प्राप्त करने के लिए बाल्टी आकार के साथ खेलना होगा। बहुत बड़े आवंटन वीएम पता प्रबंधक से सीधे आते हैं।

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

यह योजना आपको किसी भी ढेर और ढेर बनाने की अनुमति देती है।