स्टैक-आधारित मेमोरी आवंटन: Difference between revisions

From Vigyanwiki
 
Line 12: Line 12:
एक थ्रेड का निर्धारित स्टैक आकार कुछ छोटे सीपीयू पर केवल कुछ बाइट्स जितना छोटा हो सकता है। स्टैक पर उपलब्ध मेमोरी से अधिक मेमोरी आवंटित करने से [[ स्टैक ओवरफ़्लो |स्टैक ओवरफ़्लो]] के कारण [[क्रैश (कंप्यूटिंग)]] हो सकता है। यही कारण है कि उपयोग करने वाले कार्य {{code|alloca}} को सामान्यतः इनलाइन होने से रोका जाता है:<ref>{{cite web |title=इन - लाइन|url=http://gcc.gnu.org/onlinedocs/gcc/Inline.html |website=Using the GNU Compiler Collection (GCC)}}</ref> क्या इस तरह के फ़ंक्शन को लूप में रेखांकित किया जाना चाहिए, कॉल करने वाले को स्टैक के उपयोग में अप्रत्याशित वृद्धि से पीड़ित होना चाहिए, जिससे अतिप्रवाह अधिक होने की संभावना है।
एक थ्रेड का निर्धारित स्टैक आकार कुछ छोटे सीपीयू पर केवल कुछ बाइट्स जितना छोटा हो सकता है। स्टैक पर उपलब्ध मेमोरी से अधिक मेमोरी आवंटित करने से [[ स्टैक ओवरफ़्लो |स्टैक ओवरफ़्लो]] के कारण [[क्रैश (कंप्यूटिंग)]] हो सकता है। यही कारण है कि उपयोग करने वाले कार्य {{code|alloca}} को सामान्यतः इनलाइन होने से रोका जाता है:<ref>{{cite web |title=इन - लाइन|url=http://gcc.gnu.org/onlinedocs/gcc/Inline.html |website=Using the GNU Compiler Collection (GCC)}}</ref> क्या इस तरह के फ़ंक्शन को लूप में रेखांकित किया जाना चाहिए, कॉल करने वाले को स्टैक के उपयोग में अप्रत्याशित वृद्धि से पीड़ित होना चाहिए, जिससे अतिप्रवाह अधिक होने की संभावना है।


अतः स्टैक-आधारित आवंटन सामान्य प्रदर्शन समस्याएं भी उत्पन्न कर सकता है: यह वेरिएबल्स -आकार के स्टैक फ़्रेमों की ओर जाता है, जिससे दोनों कॉल स्टैक या स्टैक पॉइंटर को प्रबंधित करने की आवश्यकता हो (निश्चित आकार के स्टैक फ़्रेमों के साथ, स्टैक पॉइंटर बेमानी है क्योंकि स्टैक फ्रेम पॉइंटर प्रत्येक फ्रेम के आकार से)। यह सामान्यतः कॉल करने की तुलना में बहुत कम व्यय होता है {{code|malloc}} और {{code|free}} इसके पश्चात विशेष रूप से, यदि वर्तमान फ़ंक्शन में एलोका और वेरिएबल्स -लंबाई वाले स्थानीय डेटा वाले ब्लॉक दोनों कॉल सम्मिलित होते हैं, तो वर्तमान स्टैक फ्रेम को बढ़ाने के लिए एलोका के प्रयासों के बीच संघर्ष होता है, जब तक कि वर्तमान फ़ंक्शन बाहर नहीं निकलता है बनाम संकलक की वेरिएबल्स लंबाई के स्थानीय वेरिएबल्स को रखने की आवश्यकता होती है। स्टैक फ्रेम में ही स्थान होता है। एलोका को प्रत्येक कॉल के लिए स्टैक भंडारण की अलग श्रृंखला बनाकर इस विरोध को सामान्यतः हल किया जाता है।<ref>{{cite web | url=https://code.woboq.org/gcc/libiberty/alloca.c.html | title=Alloca.c source code &#91;libiberty/Alloca.c&#93; - Codebrowser }}</ref> श्रृंखला स्टैक की गहराई को रिकॉर्ड करती है जिस पर प्रत्येक आवंटन होता है, इसके पश्चात किसी भी फ़ंक्शन में एलोका को कॉल करता है, इस श्रृंखला को वर्तमान स्टैक गहराई तक ट्रिम कर देता है जिससे अंततः (किन्तु तुरंत नहीं) इस श्रृंखला पर कोई भंडारण मुक्त हो सकते है। और शून्य विधि के साथ एलोका को कॉल करने के लिए भी ऐसी मेमोरी आवंटित किए बिना मेमोरी को मुक्त करने के लिए उपयोग किया जा सकता है। एलोका और स्थानीय वेरिएबल्स भंडारण के बीच इस संघर्ष के परिणामस्वरूप, एलोका का उपयोग करना मॉलोक का उपयोग करने से अधिक कुशल नहीं हो सकता है।
अतः स्टैक-आधारित आवंटन सामान्य प्रदर्शन समस्याएं भी उत्पन्न कर सकता है: यह वेरिएबल्स -आकार के स्टैक फ़्रेमों की ओर जाता है, जिससे दोनों कॉल स्टैक या स्टैक पॉइंटर को प्रबंधित करने की आवश्यकता हो (निश्चित आकार के स्टैक फ़्रेमों के साथ, स्टैक पॉइंटर निरर्थक है क्योंकि स्टैक फ्रेम पॉइंटर प्रत्येक फ्रेम के आकार से)। यह सामान्यतः कॉल करने की तुलना में बहुत कम व्यय होता है {{code|malloc}} और {{code|free}} इसके पश्चात विशेष रूप से, यदि वर्तमान फ़ंक्शन में एलोका और वेरिएबल्स -लंबाई वाले स्थानीय डेटा वाले ब्लॉक दोनों कॉल सम्मिलित होते हैं, तो वर्तमान स्टैक फ्रेम को बढ़ाने के लिए एलोका के प्रयासों के बीच संघर्ष होता है, जब तक कि वर्तमान फ़ंक्शन बाहर नहीं निकलता है बनाम संकलक की वेरिएबल्स लंबाई के स्थानीय वेरिएबल्स को रखने की आवश्यकता होती है। स्टैक फ्रेम में ही स्थान होता है। एलोका को प्रत्येक कॉल के लिए स्टैक भंडारण की अलग श्रृंखला बनाकर इस विरोध को सामान्यतः हल किया जाता है।<ref>{{cite web | url=https://code.woboq.org/gcc/libiberty/alloca.c.html | title=Alloca.c source code &#91;libiberty/Alloca.c&#93; - Codebrowser }}</ref> श्रृंखला स्टैक की गहराई को रिकॉर्ड करती है जिस पर प्रत्येक आवंटन होता है, इसके पश्चात किसी भी फ़ंक्शन में एलोका को कॉल करता है, इस श्रृंखला को वर्तमान स्टैक गहराई तक ट्रिम कर देता है जिससे अंततः (किन्तु तुरंत नहीं) इस श्रृंखला पर कोई भंडारण मुक्त हो सकते है। और शून्य विधि के साथ एलोका को कॉल करने के लिए भी ऐसी मेमोरी आवंटित किए बिना मेमोरी को मुक्त करने के लिए उपयोग किया जा सकता है। एलोका और स्थानीय वेरिएबल्स भंडारण के बीच इस संघर्ष के परिणामस्वरूप, एलोका का उपयोग करना मॉलोक का उपयोग करने से अधिक कुशल नहीं हो सकता है।


== सिस्टम इंटरफ़ेस ==
== सिस्टम इंटरफ़ेस ==

Latest revision as of 12:36, 28 August 2023

नेस्टेड प्रक्रिया कॉल के लिए स्थानीय आंकड़े और कॉल जानकारी संग्रहीत करने वाला विशिष्ट स्टैक (जरूरी नहीं कि नेस्टेड प्रक्रियाएँ)। यह स्टैक अपने मूल स्थान से नीचे की ओर बढ़ता है। स्टैक पॉइंटर स्टैक पर वर्तमान शीर्षतम डेटा को इंगित करता है। पुश ऑपरेशन पॉइंटर को घटाता है और डेटा को स्टैक पर कॉपी करता है; पॉप ऑपरेशन स्टैक से डेटा कॉपी करता है और फिर पॉइंटर को बढ़ाता है। प्रोग्राम में बुलाई जाने वाली प्रत्येक प्रक्रिया स्टैक पर पुश करके प्रक्रिया वापसी जानकारी (पीले रंग में) और स्थानीय डेटा (अन्य रंगों में) को संग्रहीत करती है।

स्टैक (अमूर्त डेटा प्रकार) या हार्डवेयर स्टैक कंप्यूटिंग आर्किटेक्वेरिएबल्स में मेमोरी (कंप्यूटर) के क्षेत्र हैं जहां डेटा को एलआईएफओ (कंप्यूटिंग) लास्ट-इन-फर्स्ट-आउट (एलआईएफओ) विधियों से जोड़ा या हटाया जाता है।

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

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

फायदे और हानि

क्योंकि डेटा को लास्ट-इन-फर्स्ट-आउट विधियों से जोड़ा और हटाया जाता है, स्टैक-आधारित मेमोरी एलोकेशन बहुत सरल होते है और सामान्यतः हीप-आधारित मेमोरी एलोकेशन (डायनामिक मेमोरी आवंटन के रूप में भी जाना जाता है) की तुलना में बहुत तीव्र होते है। सी (प्रोग्रामिंग भाषा)malloc.

इस प्रकार से अन्य विशेषता यह है कि स्टैक पर मेमोरी स्वचालित रूप से और बहुत कुशलता से, फ़ंक्शन से बाहर निकलने पर पुनः प्राप्त होती है, जो प्रोग्रामर के लिए सुविधाजनक हो सकती है यदि डेटा की आवश्यकता नहीं है।[1] (यही बात setjmp.h पर भी प्रयुक्त होती है यदि यह कॉल करने से पहले बिंदु पर चली जाती है alloca हुआ।) चूँकि, यदि डेटा को किसी रूप में रखने की आवश्यकता होती है, तो फ़ंक्शन से बाहर निकलने से पहले इसे स्टैक से हीप में कॉपी किया जाना चाहिए। इसलिए, स्टैक आधारित आवंटन अस्थायी डेटा या डेटा के लिए उपयुक्त है जो वर्तमान फ़ंक्शन के बाहर निकलने के बाद आवश्यक नहीं है।

एक थ्रेड का निर्धारित स्टैक आकार कुछ छोटे सीपीयू पर केवल कुछ बाइट्स जितना छोटा हो सकता है। स्टैक पर उपलब्ध मेमोरी से अधिक मेमोरी आवंटित करने से स्टैक ओवरफ़्लो के कारण क्रैश (कंप्यूटिंग) हो सकता है। यही कारण है कि उपयोग करने वाले कार्य alloca को सामान्यतः इनलाइन होने से रोका जाता है:[2] क्या इस तरह के फ़ंक्शन को लूप में रेखांकित किया जाना चाहिए, कॉल करने वाले को स्टैक के उपयोग में अप्रत्याशित वृद्धि से पीड़ित होना चाहिए, जिससे अतिप्रवाह अधिक होने की संभावना है।

अतः स्टैक-आधारित आवंटन सामान्य प्रदर्शन समस्याएं भी उत्पन्न कर सकता है: यह वेरिएबल्स -आकार के स्टैक फ़्रेमों की ओर जाता है, जिससे दोनों कॉल स्टैक या स्टैक पॉइंटर को प्रबंधित करने की आवश्यकता हो (निश्चित आकार के स्टैक फ़्रेमों के साथ, स्टैक पॉइंटर निरर्थक है क्योंकि स्टैक फ्रेम पॉइंटर प्रत्येक फ्रेम के आकार से)। यह सामान्यतः कॉल करने की तुलना में बहुत कम व्यय होता है malloc और free इसके पश्चात विशेष रूप से, यदि वर्तमान फ़ंक्शन में एलोका और वेरिएबल्स -लंबाई वाले स्थानीय डेटा वाले ब्लॉक दोनों कॉल सम्मिलित होते हैं, तो वर्तमान स्टैक फ्रेम को बढ़ाने के लिए एलोका के प्रयासों के बीच संघर्ष होता है, जब तक कि वर्तमान फ़ंक्शन बाहर नहीं निकलता है बनाम संकलक की वेरिएबल्स लंबाई के स्थानीय वेरिएबल्स को रखने की आवश्यकता होती है। स्टैक फ्रेम में ही स्थान होता है। एलोका को प्रत्येक कॉल के लिए स्टैक भंडारण की अलग श्रृंखला बनाकर इस विरोध को सामान्यतः हल किया जाता है।[3] श्रृंखला स्टैक की गहराई को रिकॉर्ड करती है जिस पर प्रत्येक आवंटन होता है, इसके पश्चात किसी भी फ़ंक्शन में एलोका को कॉल करता है, इस श्रृंखला को वर्तमान स्टैक गहराई तक ट्रिम कर देता है जिससे अंततः (किन्तु तुरंत नहीं) इस श्रृंखला पर कोई भंडारण मुक्त हो सकते है। और शून्य विधि के साथ एलोका को कॉल करने के लिए भी ऐसी मेमोरी आवंटित किए बिना मेमोरी को मुक्त करने के लिए उपयोग किया जा सकता है। एलोका और स्थानीय वेरिएबल्स भंडारण के बीच इस संघर्ष के परिणामस्वरूप, एलोका का उपयोग करना मॉलोक का उपयोग करने से अधिक कुशल नहीं हो सकता है।

सिस्टम इंटरफ़ेस

कई यूनिक्स-जैसी प्रणालियाँ और साथ ही माइक्रोसॉफ़्ट विंडोज़ नामक कार्य को प्रयुक्त करते हैं alloca हीप-आधारित के समान स्टैक मेमोरी को डायनामिक रूप से आवंटित करने के लिए malloc. कंपाइलर सामान्यतः इसे स्टैक पॉइंटर में हेरफेर करने वाले इनलाइन निर्देशों में अनुवाद करता है, जैसा कि वेरिएबल्स -लंबाई सरणी को हैंडल किया जाता है।[4] चूँकि मेमोरी को स्पष्ट रूप से मुक्त करने की कोई आवश्यकता नहीं है, स्टैक ओवरफ़्लो के कारण अपरिभाषित व्यवहार का संकट है।[5] यह कार्य यूनिक्स/32वी|32/वी (1978) से ही यूनिक्स सिस्टम पर उपस्तिथ होता है, किन्तु यह मानक C या किसी पॉज़िक्स मानक का भाग नहीं होता है।

इस प्रकासर से सुरक्षित संस्करण alloca नाम _malloca, जो त्रुटियों की रिपोर्ट करता है, माइक्रोसॉफ्ट विन्डोज़ पर उपस्तिथ रहते है। इसके उपयोग की आवश्यकता है _freea.[6] ग्नुलिब समतुल्य इंटरफ़ेस प्रदान करता है, चूँकि अतिप्रवाह पर एसईएच अपवाद व्यर्थ करने के अतिरिक्त, यह प्रतिनिधि करता है malloc जब उच्च आकार का पता चलता है।[7] इसी प्रकार की सुविधा को मैन्युअल लेखा और आकार-जांच का उपयोग करके अनुकरण किया जा सकता है, जैसे कि उपयोग में alloca_account ग्लिब में।[8]

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

ऑटो वीएलए

इसके अतिरिक्त, C संस्करण C99 (C11 के बाद से वैकल्पिक) के बाद से, फ़ंक्शन के अंदर स्टैक पर सरणी बनाना संभव होता है, स्वचालित रूप से, ऑटो वीएलए (वेरिएबल्स -लंबाई सरणी) के रूप में जाना जाता है।[9]

void f(int alen)
{
  int b[alen]; // auto VLA - this array's length is set at 
               // the time of the function invocation / stack generation.
  for (int i = 0; i < alen; i++)
    b[i] = 1;
  // at the end of this function, b[] is within the stack frame, and will 
  // disappear when the function exits, so no explicit call to free() is required.
}

यह भी देखें

संदर्भ

  1. "एलोका के फायदे". The GNU C Library.
  2. "इन - लाइन". Using the GNU Compiler Collection (GCC).
  3. "Alloca.c source code [libiberty/Alloca.c] - Codebrowser".
  4. alloca(3) – Linux Programmer's Manual – Library Functions
  5. "Why is the use of alloca() not considered good practice?". stackoverflow.com. Retrieved 2016-01-05.
  6. "_malloca". Microsoft CRT Documentation (in English).
  7. "gnulib/malloca.h". GitHub. Retrieved 24 November 2019.
  8. "glibc/include/alloca.h". Beren Minor's Mirrors. 23 November 2019.
  9. "ISO C 99 Definition" (PDF). Retrieved 2022-04-10.