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

आइए लिनक्स मेमोरी आवंटन को विस्तार से देखें और समझें कि पर्दे के पीछे क्या होता है।

मेमोरी आवंटन कैसे किया जाता है?

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

जब एप्लिकेशन को मेमोरी की आवश्यकता होती है, तो उन्हें ऑपरेटिंग सिस्टम से इसके लिए अनुरोध करना पड़ता है। कर्नेल के इस अनुरोध के लिए स्वाभाविक रूप से सिस्टम कॉल की आवश्यकता होगी। आप उपयोगकर्ता मोड में स्वयं स्मृति आवंटित नहीं कर सकते हैं।

मॉलोक () सी भाषा में स्मृति आवंटन के लिए कार्यों का परिवार जिम्मेदार है। यहां पूछने का सवाल यह है कि क्या ग्लिबक फ़ंक्शन के रूप में मॉलोक (), प्रत्यक्ष सिस्टम कॉल करता है।

instagram viewer

लिनक्स कर्नेल में मॉलोक नामक कोई सिस्टम कॉल नहीं है। हालाँकि, एप्लिकेशन मेमोरी डिमांड के लिए दो सिस्टम कॉल हैं, जो हैं नि: और एमएमएपी.

चूंकि आप glibc फ़ंक्शन के माध्यम से अपने एप्लिकेशन में मेमोरी का अनुरोध कर रहे होंगे, आप सोच रहे होंगे कि इनमें से कौन सा सिस्टम कॉल glibc इस समय उपयोग कर रहा है। उत्तर दोनों है।

पहला सिस्टम कॉल: brk

प्रत्येक प्रक्रिया में एक सन्निहित डेटा फ़ील्ड होता है। brk सिस्टम कॉल के साथ, प्रोग्राम ब्रेक वैल्यू, जो डेटा फ़ील्ड की सीमा निर्धारित करती है, बढ़ जाती है और आवंटन प्रक्रिया की जाती है।

हालांकि इस पद्धति के साथ स्मृति आवंटन बहुत तेज है, सिस्टम में अप्रयुक्त स्थान को वापस करना हमेशा संभव नहीं होता है।

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

इस परिदृश्य में स्मृति हानि को रोकने के लिए, ग्लिब में मॉलोक कार्यान्वयन प्रक्रिया डेटा फ़ील्ड में आवंटित स्थानों की निगरानी करता है और फिर इसे फ्री () फ़ंक्शन के साथ सिस्टम में वापस करने के लिए निर्दिष्ट करता है, ताकि सिस्टम आगे की मेमोरी के लिए खाली स्थान का उपयोग कर सके आवंटन।

दूसरे शब्दों में, पांच 16 केबी क्षेत्र आवंटित किए जाने के बाद, यदि दूसरा क्षेत्र मुफ्त () फ़ंक्शन और अन्य 16 केबी क्षेत्र के साथ वापस किया जाता है थोड़ी देर बाद फिर से अनुरोध किया जाता है, brk सिस्टम कॉल के माध्यम से डेटा क्षेत्र को बढ़ाने के बजाय, पिछला पता वापस कर दिया जाता है।

हालाँकि, यदि नया अनुरोधित क्षेत्र 16KB से बड़ा है, तो डेटा क्षेत्र को brk सिस्टम कॉल के साथ एक नया क्षेत्र आवंटित करके बढ़ाया जाएगा क्योंकि क्षेत्र दो का उपयोग नहीं किया जा सकता है। हालांकि क्षेत्र संख्या दो उपयोग में नहीं है, आकार अंतर के कारण एप्लिकेशन इसका उपयोग नहीं कर सकता है। इस तरह के परिदृश्यों के कारण, आंतरिक विखंडन नामक एक स्थिति होती है, और वास्तव में, आप शायद ही कभी स्मृति के सभी भागों का पूर्ण रूप से उपयोग कर सकते हैं।

बेहतर समझ के लिए, निम्नलिखित नमूना एप्लिकेशन को संकलित और चलाने का प्रयास करें:

#शामिल करना <stdio.h>
#शामिल करना <stdlib.h>
#शामिल करना <unistd.h>
पूर्णांकमुख्य(पूर्णांक आर्गसी, चारो* एआरजीवी [])
{
चारो *पीटीआर[7];
पूर्णांक एन;
प्रिंटफ ("%s का पिड: %d", argv [0], गेटपिड ());
प्रिंटफ ("प्रारंभिक कार्यक्रम विराम: %p", एसबीआरके (0));
के लिए (एन = 0; एन<5; एन ++) पीटीआर [एन] = मॉलोक (16 * 1024);
प्रिंटफ ("5 x 16kB के बाद मॉलोक: %p", एसबीआरके (0));
नि: शुल्क(पीटीआर[1]);
प्रिंटफ ("दूसरे 16kB से मुक्त होने के बाद: %p", एसबीआरके (0));
पीटीआर [5] = मॉलोक (16 * 1024);
प्रिंटफ ("16kB में से छठा आवंटन करने के बाद: %p", एसबीआरके (0));
नि: शुल्क(पीटीआर[5]);
प्रिंटफ ("अंतिम ब्लॉक मुक्त करने के बाद: %p", एसबीआरके (0));
पीटीआर [6] = मॉलोक (18 * 1024);
प्रिंटफ ("एक नया 18kB आवंटित करने के बाद: %p", एसबीआरके (0));
गेटचर ();
वापसी0;
}

जब आप एप्लिकेशन चलाते हैं तो आपको निम्न आउटपुट के समान परिणाम मिलेगा:

./a.out का पिड: 31990
प्रारंभिक कार्यक्रम टूटना: 0x55ebcadf4000
5 x 16kB मॉलोक के बाद: 0x55ebcadf4000
दूसरे 16kB से मुक्त होने के बाद: 0x55ebcadf4000
16kB का 6वां आवंटन करने के बाद: 0x55ebcadf4000
अंतिम ब्लॉक मुक्त करने के बाद: 0x55ebcadf4000
आवंटित करने के बाद a नवीन व18केबी: 0x55ebcadf4000

स्ट्रेस के साथ brk का आउटपुट इस प्रकार होगा:

बीआरके(व्यर्थ) = 0x5608595b6000
ब्रिक (0x5608595d7000) = 0x5608595d7000

जैसा कि आप देख सकते हैं, 0x21000 डेटा फ़ील्ड के अंतिम पते में जोड़ा गया है। इसे आप Value से समझ सकते हैं 0x5608595d7000. तो लगभग 0x21000, या 132KB मेमोरी आवंटित की गई थी।

यहां विचार करने के लिए दो महत्वपूर्ण बिंदु हैं। पहला नमूना कोड में निर्दिष्ट राशि से अधिक का आवंटन है। दूसरा यह है कि कोड की कौन सी लाइन आवंटन प्रदान करने वाले ब्रैक कॉल का कारण बनती है।

एड्रेस स्पेस लेआउट रैंडमाइजेशन: ASLR

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

हालांकि, 32-बिट आर्किटेक्चर में, आठ बिट्स का उपयोग आमतौर पर एड्रेस स्पेस को रैंडमाइज करने के लिए किया जाता है। बिट्स की संख्या बढ़ाना उचित नहीं होगा क्योंकि शेष बिट्स पर एड्रेसेबल क्षेत्र बहुत कम होगा। साथ ही, केवल 8-बिट संयोजनों के उपयोग से हमलावर के लिए चीजें काफी कठिन नहीं होती हैं।

दूसरी ओर, 64-बिट आर्किटेक्चर में, बहुत अधिक बिट्स हैं जिन्हें ASLR ऑपरेशन के लिए आवंटित किया जा सकता है, बहुत अधिक यादृच्छिकता प्रदान की जाती है, और सुरक्षा की डिग्री बढ़ जाती है।

लिनक्स कर्नेल भी शक्तियाँ Android-आधारित डिवाइस और ASLR सुविधा Android 4.0.3 और बाद के संस्करणों पर पूरी तरह से सक्रिय है। अकेले इस कारण से भी, यह कहना गलत नहीं होगा कि 64-बिट स्मार्टफोन 32-बिट संस्करणों पर एक महत्वपूर्ण सुरक्षा लाभ प्रदान करता है।

निम्न आदेश के साथ एएसएलआर सुविधा को अस्थायी रूप से अक्षम करने से, ऐसा प्रतीत होगा कि पिछला परीक्षण अनुप्रयोग हर बार चलने पर समान पता मान लौटाता है:

गूंज0 | सुडो टी / प्रोक / एसआईएस / कर्नेल / रैंडमाइज_वा_स्पेस

इसे अपनी पिछली स्थिति में पुनर्स्थापित करने के लिए, एक ही फ़ाइल में 0 के बजाय 2 लिखना पर्याप्त होगा।

दूसरा सिस्टम कॉल: mmap

एमएमएपी लिनक्स पर मेमोरी आवंटन के लिए इस्तेमाल किया जाने वाला दूसरा सिस्टम कॉल है। एमएमएपी कॉल के साथ, मेमोरी के किसी भी क्षेत्र में खाली स्थान को कॉलिंग प्रक्रिया के एड्रेस स्पेस में मैप किया जाता है।

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

क्योंकि एमएमएपी के साथ मेमोरी आवंटन brk वाले लोगों की तुलना में बहुत धीमा है, इसलिए brk आवंटन की आवश्यकता है।

एमएमएपी के साथ, स्मृति के किसी भी मुक्त क्षेत्र को प्रक्रिया के पता स्थान पर मैप किया जाता है, इसलिए आवंटित स्थान की सामग्री को इस प्रक्रिया के पूरा होने से पहले रीसेट कर दिया जाता है। यदि रीसेट इस तरह से नहीं किया गया था, तो उस प्रक्रिया से संबंधित डेटा जो पहले संबंधित मेमोरी क्षेत्र का उपयोग करता था, उसे अगली असंबंधित प्रक्रिया द्वारा भी एक्सेस किया जा सकता है। इससे सिस्टम में सुरक्षा के बारे में बात करना असंभव हो जाएगा।

लिनक्स में मेमोरी आवंटन का महत्व

स्मृति आवंटन बहुत महत्वपूर्ण है, विशेष रूप से अनुकूलन और सुरक्षा मुद्दों में। जैसा कि ऊपर के उदाहरणों में देखा गया है, इस मुद्दे को पूरी तरह से न समझने का अर्थ आपके सिस्टम की सुरक्षा को नष्ट करना हो सकता है।

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

यदि आप भी अपने पैर की उंगलियों को लिनक्स कर्नेल विकास में डुबाना चाहते हैं, तो पहले सी प्रोग्रामिंग भाषा में महारत हासिल करने पर विचार करें।

सी प्रोग्रामिंग भाषा का संक्षिप्त परिचय

आगे पढ़िए

साझा करनाकलरवसाझा करनाईमेल

संबंधित विषय

  • लिनक्स
  • स्मृति
  • लिनक्स कर्नेल

लेखक के बारे में

फ़ातिह कुकुक्कराकुर्ती (7 लेख प्रकाशित)

एक इंजीनियर और सॉफ्टवेयर डेवलपर जो गणित और प्रौद्योगिकी का प्रशंसक है। उन्हें हमेशा कंप्यूटर, गणित और भौतिकी पसंद रही है। उन्होंने गेम इंजन प्रोजेक्ट के साथ-साथ मशीन लर्निंग, कृत्रिम तंत्रिका नेटवर्क और रैखिक बीजगणित पुस्तकालय विकसित किए हैं। इसके अलावा मशीन लर्निंग और लीनियर मैट्रिसेस पर काम करना जारी है।

Fatih Küçükkarakurt की और फ़िल्में या टीवी शो

हमारे समाचार पत्र के सदस्य बनें

तकनीकी युक्तियों, समीक्षाओं, निःशुल्क ई-पुस्तकों और अनन्य सौदों के लिए हमारे न्यूज़लेटर से जुड़ें!

सब्सक्राइब करने के लिए यहां क्लिक करें