संक्षेप में
स्टैक का उपयोग स्थिर मेमोरी आवंटन और डायनेमिक मेमोरी आवंटन के लिए एक ढेर के लिए किया जाता है, दोनों को कंप्यूटर की रैम में संग्रहीत किया जाता है।
विस्तार से
ढेर
स्टैक एक "LIFO" (आखिरी में, पहले आउट) डेटा संरचना है, जो सीपीयू द्वारा प्रबंधित और अनुकूलित किया जाता है। हर बार जब कोई फ़ंक्शन नया चर घोषित करता है, तो उसे स्टैक पर "पुश" किया जाता है। फिर हर बार जब कोई फ़ंक्शन निकलता है, तो उस फ़ंक्शन द्वारा स्टैक पर धकेल दिए गए सभी चर मुक्त हो जाते हैं (यह कहना है, वे हटा दिए जाते हैं)। एक बार एक स्टैक चर मुक्त हो जाने के बाद, मेमोरी का वह क्षेत्र अन्य स्टैक चर के लिए उपलब्ध हो जाता है।
वैरिएबल को स्टोर करने के लिए स्टैक का उपयोग करने का लाभ यह है कि मेमोरी आपके लिए प्रबंधित है। आपको स्मृति को हाथ से आवंटित करने की आवश्यकता नहीं है, या इसे एक बार मुक्त करने की आवश्यकता नहीं है। क्या अधिक है, क्योंकि सीपीयू स्टैक मेमोरी को इतनी कुशलता से व्यवस्थित करता है, स्टैक चर से पढ़ना और लिखना बहुत तेज है।
अधिक यहाँ पाया जा सकता है ।
ढेर
ढेर आपके कंप्यूटर की मेमोरी का एक क्षेत्र है जो आपके लिए स्वचालित रूप से प्रबंधित नहीं है, और सीपीयू द्वारा कसकर प्रबंधित नहीं है। यह स्मृति का अधिक मुक्त-तैरता क्षेत्र है (और बड़ा है)। स्मृति को ढेर पर आवंटित करने के लिए, आपको मॉलोक () या कॉलोक () का उपयोग करना होगा, जो अंतर्निहित सी फ़ंक्शन हैं। एक बार जब आपने हीप पर मेमोरी आवंटित की है, तो आप उस मेमोरी को डील करने के लिए मुफ्त () का उपयोग करने के लिए जिम्मेदार हैं, जब आपको इसकी आवश्यकता नहीं है।
यदि आप ऐसा करने में विफल रहते हैं, तो आपके कार्यक्रम में मेमोरी लीक के रूप में जाना जाता है। यही है, ढेर पर मेमोरी अभी भी अलग रखी जाएगी (और अन्य प्रक्रियाओं के लिए उपलब्ध नहीं होगी)। जैसा कि हम डिबगिंग अनुभाग में देखेंगे, Valgrind नामक एक उपकरण है जो आपको मेमोरी लीक का पता लगाने में मदद कर सकता है।
स्टैक के विपरीत, ढेर में परिवर्तनशील आकार (आपके कंप्यूटर की स्पष्ट भौतिक सीमाओं के अलावा) पर आकार प्रतिबंध नहीं है। हीप मेमोरी को पढ़ने और लिखने के लिए थोड़ा धीमा है, क्योंकि एक को ढेर पर मेमोरी तक पहुंचने के लिए पॉइंटर्स का उपयोग करना पड़ता है। हम शीघ्र ही संकेत के बारे में बात करेंगे।
स्टैक के विपरीत, ढेर पर बनाए गए चर आपके कार्यक्रम में कहीं भी, किसी भी फ़ंक्शन द्वारा सुलभ हैं। ढेर चर अनिवार्य रूप से दायरे में वैश्विक हैं।
अधिक यहाँ पाया जा सकता है ।
स्टैक पर आवंटित चर को सीधे मेमोरी में संग्रहीत किया जाता है और इस मेमोरी तक पहुंच बहुत तेज है, और जब प्रोग्राम संकलित किया जाता है, तो इसके आवंटन से निपटा जाता है। जब कोई फ़ंक्शन या कोई विधि किसी अन्य फ़ंक्शन को कॉल करती है, जो किसी अन्य फ़ंक्शन आदि को कॉल करती है, तो उन सभी फ़ंक्शन का निष्पादन तब तक निलंबित रहता है जब तक कि बहुत अंतिम फ़ंक्शन उसका मान वापस नहीं करता है। स्टैक हमेशा एक LIFO क्रम में आरक्षित होता है, सबसे हाल ही में आरक्षित ब्लॉक को मुक्त करने के लिए हमेशा अगला ब्लॉक होता है। यह स्टैक का ट्रैक रखने के लिए वास्तव में सरल बनाता है, स्टैक से एक ब्लॉक को मुक्त करना एक पॉइंटर को समायोजित करने से ज्यादा कुछ नहीं है।
ढेर पर आवंटित चर को उनकी मेमोरी को रन टाइम पर आवंटित किया जाता है और इस मेमोरी को एक्सेस करना थोड़ा धीमा है, लेकिन हीप का आकार केवल वर्चुअल मेमोरी के आकार तक सीमित है। ढेर के तत्वों की एक दूसरे के साथ कोई निर्भरता नहीं है और हमेशा किसी भी समय यादृच्छिक रूप से एक्सेस किया जा सकता है। आप किसी भी समय एक ब्लॉक आवंटित कर सकते हैं और इसे किसी भी समय मुक्त कर सकते हैं। इससे यह अधिक जटिल हो जाता है कि किसी भी समय ढेर के किन हिस्सों को आवंटित या मुफ्त किया जाए।
आप स्टैक का उपयोग कर सकते हैं यदि आप जानते हैं कि संकलन समय से पहले आपको कितना डेटा आवंटित करने की आवश्यकता है, और यह बहुत बड़ा नहीं है। आप हीप का उपयोग कर सकते हैं यदि आपको ठीक से पता नहीं है कि रनटाइम में आपको कितने डेटा की आवश्यकता होगी या यदि आपको बहुत अधिक डेटा आवंटित करने की आवश्यकता है।
बहु-थ्रेडेड स्थिति में प्रत्येक थ्रेड का अपना पूर्ण स्वतंत्र स्टैक होगा, लेकिन वे ढेर साझा करेंगे। स्टैक थ्रेड विशिष्ट है और हीप एप्लिकेशन विशिष्ट है। स्टैक अपवाद हैंडलिंग और थ्रेड निष्पादन में विचार करने के लिए महत्वपूर्ण है।
प्रत्येक धागे को एक स्टैक मिलता है, जबकि आमतौर पर आवेदन के लिए केवल एक हीप होता है (हालांकि विभिन्न प्रकार के आवंटन के लिए कई ढेर होना असामान्य नहीं है)।
रन-टाइम पर, यदि एप्लिकेशन को अधिक हीप की आवश्यकता होती है, तो यह मेमोरी को फ्री मेमोरी से आवंटित कर सकता है और यदि स्टैक को मेमोरी की आवश्यकता होती है, तो यह एप्लिकेशन के लिए फ्री मेमोरी आवंटित मेमोरी से मेमोरी को आवंटित कर सकता है।
यहां तक कि, और अधिक विस्तार दिया जाता है यहाँ और यहाँ ।
अब आपके प्रश्न के उत्तर आते हैं ।
ओएस या भाषा रनटाइम द्वारा उन्हें किस हद तक नियंत्रित किया जाता है?
जब ओएस बनाया जाता है तो ओएस प्रत्येक सिस्टम-स्तरीय थ्रेड के लिए स्टैक आवंटित करता है। आमतौर पर आवेदन के लिए ढेर आवंटित करने के लिए भाषा रनटाइम द्वारा ओएस को बुलाया जाता है।
अधिक यहाँ पाया जा सकता है ।
उनका दायरा क्या है?
पहले से ही शीर्ष में दिया गया है।
"आप स्टैक का उपयोग कर सकते हैं यदि आप जानते हैं कि संकलन समय से पहले आपको कितना डेटा आवंटित करने की आवश्यकता है, और यह बहुत बड़ा नहीं है। आप हीप का उपयोग कर सकते हैं यदि आपको ठीक से पता नहीं है कि आपको रनटाइम या कितने डेटा की आवश्यकता होगी। आपको बहुत अधिक डेटा आवंटित करने की आवश्यकता है। "
यहां और अधिक पाया जा सकता है ।
उनमें से प्रत्येक का आकार क्या निर्धारित करता है?
जब थ्रेड बनाया जाता है तो स्टैक का आकार OS द्वारा सेट किया जाता है। हीप का आकार एप्लिकेशन स्टार्टअप पर सेट किया गया है, लेकिन यह अंतरिक्ष की आवश्यकता के रूप में बढ़ सकता है (आवंटनकर्ता ऑपरेटिंग सिस्टम से अधिक मेमोरी का अनुरोध करता है)।
क्या एक तेज बनाता है?
स्टैक आवंटन बहुत तेज है क्योंकि यह वास्तव में स्टैक पॉइंटर को स्थानांतरित करता है। मेमोरी पूल का उपयोग करते हुए, आप ढेर आवंटन से तुलनीय प्रदर्शन प्राप्त कर सकते हैं, लेकिन यह थोड़ा जोड़ा जटिलता और अपने स्वयं के सिरदर्द के साथ आता है।
इसके अलावा, ढेर बनाम ढेर केवल एक प्रदर्शन विचार नहीं है; यह आपको वस्तुओं के अपेक्षित जीवनकाल के बारे में बहुत कुछ बताता है।
विवरण यहाँ से पाया जा सकता है ।