2010-12-21 15 views
18

बिल्कुल यकीन है कि कैसे वाक्यांश शीर्षक है, लेकिन सवाल है नहीं था लागू करने के लिए आवश्यकतानुसार इसे निपटाना। यह हर बार स्मृति की आवश्यकता होने पर ओएस पर जाने के विपरीत है। मैंने सुना है कि यह तेज़ होगा क्योंकि यह ओएस को लगातार स्मृति के ब्लॉक के लिए पूछने की लागत से बच जाएगा।कैसे एक स्मृति ढेर

मेरा मानना ​​है कि जेवीएम सिर्फ यह करता है, स्मृति के अपने स्वयं के खंड को बनाए रखता है और उसके बाद वस्तुओं को आवंटित करता है।

मेरा सवाल यह है कि, वास्तव में इसे कैसे लागू किया जाएगा?

धन्यवाद, dragonwrenn

+0

"ओएस पर जाने" का क्या मतलब है? ढेर पूरी तरह से उपयोगकर्ता मोड में लागू होते हैं, और प्रत्येक ढेर आवंटन के लिए सिस्टम कॉल की आवश्यकता नहीं होती है जब तक कि अधिक पृष्ठों को आवंटित करने की आवश्यकता न हो। या आप कुछ अलग सोच रहे हैं? – wj32

+2

प्रश्न "मैं मेमोरी मैनेजर को कैसे कार्यान्वित कर सकता हूं" अच्छा है, लेकिन आपको यह सुनिश्चित करना होगा कि आपको वास्तव में इसकी आवश्यकता है। यदि आप इसे प्रशिक्षण के लिए करते हैं या बस मस्ती के लिए करते हैं - ठीक है। यदि आप निश्चित रूप से जानते हैं कि स्मृति आवंटन आपके कार्यक्रम में एक बाधा है तो आपको सबसे पहले अपने कार्यक्रम को फिर से डिजाइन करने पर विचार करना चाहिए ताकि यह बड़े हिस्से को आवंटित कर सके। केवल ऐसा करने के बाद आपको अपने मेमोरी मैनेजर के लिए जाना चाहिए। – sharptooth

उत्तर

14

अधिकांश सी और सी ++ कंपाइलर्स पहले से ही मानक लाइब्रेरी के हिस्से के रूप में एक हीप मेमोरी-मैनेजर प्रदान करते हैं, इसलिए आपको प्रत्येक अनुरोध के साथ ओएस को मारने से बचने के लिए कुछ भी करने की आवश्यकता नहीं है।

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

  • अनुरोध ओएस
  • से एक लिंक्ड सूची रखें:

    आप एक सीखने व्यायाम के रूप में अपने स्वयं के ढेर प्रबंधक लिखना चाहते हैं, तो यहाँ बुनियादी बातें यह करने की जरूरत नहीं है

    • एक ब्लॉक है कि अनुरोध आकार प्लस कुछ किताब रखने के साथ-साथ संग्रहीत चर के लिए काफी बड़ा है के लिए सूची की खोज: मुक्त ब्लॉक
    • आवंटन अनुरोध में आता है।
    • वर्तमान अनुरोध के लिए ब्लॉक का एक बड़ा पर्याप्त हिस्सा अलग हो गई, बाकी मुक्त सूची में वापस रख
    • अगर कोई ब्लॉक काफी बड़ा है, ओएस के लिए वापस जाओ और एक और बड़ा हिस्सा
  • के लिए पूछना
  • एक आवंटन रद्द करने का अनुरोध
    • में आता है हैडर पढ़ आकार
    • पता लगाने के लिए
    • वैकल्पिक रूप से मुक्त सूची पर नव मुक्त कर दिया ब्लॉक जोड़ने के लिए, यदि स्मृति तुरंत fol lowing भी मुक्त सूची पर सूचीबद्ध है, और एक बड़ा एक (ढेर वालों बुलाया)
+1

@ ज़ीज़ी: इसे इंगित करने के लिए धन्यवाद, अभी तय किया गया है। –

6

आप कार्यक्रम इतना बड़ा इसकी जरूरत को बनाए रखने की शुरुआत में स्मृति का एक हिस्सा आवंटित। फिर आपको इस बफर से/स्मृति को वापस करने के लिए नया और/या malloc, हटाएं और/या मुक्त करना होगा।

इस तरह के समाधान को लागू करते समय, आपको अपना खुद का आवंटक (खंड से स्रोत के लिए) लिखना होगा और आप एक से अधिक आवंटकों का उपयोग कर समाप्त कर सकते हैं, जो अक्सर आप पहली जगह मेमोरी पूल आवंटित करते हैं।

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

3

यहाँ है क्लासिक संभाजक, और गैर बहु ​​उपयोग के लिए सर्वश्रेष्ठ में से एक में दोनों आसन्न ब्लॉकों गठबंधन है:

http://g.oswego.edu/dl/html/malloc.html

आप अपने डिजाइन के विवरण को पढ़ने से बहुत कुछ सीख सकते हैं।

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

यदि आपको खुद को केवल कुछ विशिष्ट कार्यों के लिए विशेष आवंटन की आवश्यकता है, तो malloc को प्रतिस्थापित किए बिना किया जा सकता है। मैं जीएनयू obstack और निश्चित आकार के ऑब्जेक्ट्स के लिए ऑब्जेक्ट पूल देखने की अनुशंसा करता हूं। इनमें अधिकांश मामलों को शामिल किया गया है जहां विशेष आवंटन में वास्तविक व्यावहारिक उपयोग हो सकती है।

+0

संदर्भ से बाहर - एसओ पर आपके द्वारा दिए गए संदर्भ बहुत अच्छे हैं। मैं सोचता रहता हूं कि उन्हें सीमित करने के लिए मेरी स्मृति के रूप में उन्हें कैसे प्रबंधित किया जाए :-(। –

1
  1. हां, दोनों stdlib ढेर और ओएस ढेर/वर्चुअल मेमोरी बहुत परेशानी हैं। ओएस कॉल वास्तव में धीमी हैं, और stdlib तेज है, लेकिन अभी भी कुछ "अनावश्यक" ताले और चेक हैं, और आवंटित ब्लॉक (यानी कुछ स्मृति का उपयोग आपके द्वारा आवंटित किए गए कार्यों के अतिरिक्त) के लिए एक महत्वपूर्ण ओवरहेड जोड़ता है।
  2. कई मामलों में इसके बजाय स्थिर संरचनाओं का उपयोग करके गतिशील आवंटन से पूरी तरह से से बचने के लिए संभव है। उदाहरण के लिए, कभी-कभी इसके पॉइंटर/std: स्ट्रिंग और गतिशील रूप से को आवंटित करने के बजाय, यूनिकोड फ़ाइल नाम के लिए 64k स्थिर बफर को परिभाषित करने के लिए बेहतर (सुरक्षित आदि) परिभाषित किया जाता है।
  3. कार्यक्रम उसी संरचना के उदाहरण, का एक बहुत आवंटित करने के लिए है जब अपनी बहुत तेजी से बड़े स्मृति ब्लॉक और फिर बस ऐसे मामले (क्रमिक रूप से या मुफ्त नोड्स के एक लिंक्ड सूची का उपयोग करके) की दुकान आवंटित करने के लिए - सी ++ एक है इसके लिए "प्लेसमेंट नया"।
  4. कई मामलों में, जब varible आकार की वस्तुओं, संभावित आकारों के सेट के साथ काम वास्तव में बहुत ही सीमित है (उदाहरण के लिए। कुछ की तरह 4 + 2 * (1..256)) है, इसलिए इसकी संभव कुछ का उपयोग करने के पूल जैसे [3] कचरा इकट्ठा किए बिना, अंतराल भरें।
  5. विशिष्ट कार्य के लिए एक कस्टम आवंटक के लिए यह सामान्य पुस्तकालय से से अधिक तेज़ होना और गति-अनुकूलित से भी तेज़, लेकिन बहुत सार्वभौमिक कार्यान्वयन।
  6. आधुनिक सीपीयू/OSes का समर्थन "बड़े पृष्ठों", जो काफी स्मृति पहुँच गति जब आप स्पष्ट रूप से बड़े ब्लॉकों के साथ काम में सुधार कर सकते हैं - देख http://7-max.com/
1

आईबीएम डेवलपर एक साथ, स्मृति प्रबंधन के बारे में एक अच्छा लेख है आगे पढ़ने के लिए व्यापक संसाधन अनुभाग: Inside memory management

विकिपीडिया में कुछ अच्छी जानकारी भी है: C dynamic memory allocation, Memory management

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