Hacker News

पहला C++ (m)आवंटन हमेशा 72 KB क्यों होता है?

पता लगाएं कि आपका पहला C++ मेमोरी आवंटन अपेक्षित बाइट्स के बजाय 72 KB का अनुरोध क्यों करता है। बताए गए मॉलोक इंटरनल और ओएस मेमोरी प्रबंधन परतों का अन्वेषण करें।

1 मिनट पढ़ा

Mewayz Team

Editorial Team

Hacker News

आपके पहले C++ आवंटन के पीछे का रहस्य

आप एक सरल C++ प्रोग्राम लिखें. एक नया इंट. चार बाइट्स. आप स्ट्रेस या अपने पसंदीदा मेमोरी प्रोफाइलर को सक्रिय करते हैं, और यह वहां है - आपकी प्रक्रिया ने ऑपरेटिंग सिस्टम से लगभग 72 केबी का अनुरोध किया है। 4 बाइट्स नहीं. 64 बाइट्स नहीं. पूर्ण 72 KB. यदि आपने कभी उस नंबर को देखा है और सोचा है कि क्या आपका टूलींग आपसे झूठ बोल रहा है, तो आप अकेले नहीं हैं। यह प्रतीत होता है कि विचित्र व्यवहार पहली बार मेमोरी इंटरनल्स में खुदाई करने वाले C++ डेवलपर्स के बीच सबसे अक्सर पूछे जाने वाले प्रश्नों में से एक है, और इसका उत्तर हमें आपके कोड और वास्तविक हार्डवेयर के बीच की परतों के माध्यम से एक आकर्षक यात्रा पर ले जाता है।

जब आप नया कॉल करते हैं तो क्या होता है

72 केबी के आंकड़े को समझने के लिए, आपको पूरी आवंटन श्रृंखला का पता लगाना होगा। जब आपका C++ कोड नए int को निष्पादित करता है, तो कंपाइलर उसे ऑपरेटर न्यू को कॉल में अनुवादित करता है, जो अधिकांश लिनक्स सिस्टम पर glibc से मॉलोक को सौंपता है। लेकिन मॉलोक सीधे कर्नेल से 4 बाइट्स मेमोरी के लिए नहीं पूछता है। कर्नेल पृष्ठों में संचालित होता है - आमतौर पर x86_64 पर 4 KB - और एक साधारण मेमोरी एक्सेस के सापेक्ष सिस्टम कॉल की लागत बहुत अधिक होती है। प्रत्येक व्यक्तिगत आवंटन के लिए brk() या mmap() को कॉल करने से कोई भी गैर-तुच्छ कार्यक्रम रुक जाएगा।

इसके बजाय, ग्लिबैक का मेमोरी एलोकेटर - ptmalloc2 नामक एक कार्यान्वयन, जो स्वयं डौग ली के क्लासिक dlmalloc से निकला है - एक बिचौलिए के रूप में कार्य करता है। यह कर्नेल से मेमोरी के बड़े ब्लॉकों का अनुरोध करता है, फिर उन्हें छोटे टुकड़ों में काटता है क्योंकि आपके प्रोग्राम को उनकी आवश्यकता होती है। यही मूल कारण है कि आपका पहला 4-बाइट आवंटन ऑपरेटिंग सिस्टम के लिए बहुत बड़े अनुरोध को ट्रिगर करता है। आवंटनकर्ता फिजूलखर्ची नहीं कर रहा है। यह रणनीतिक हो रहा है.

72 केबी को विच्छेदित करना: बाइट्स कहाँ जाते हैं

प्रारंभिक आवंटन ओवरहेड कई अलग-अलग घटकों से आता है जिन्हें रनटाइम को प्रारंभ करने से पहले प्रारंभ करना होगा, इससे पहले कि वह आपको प्रयोग करने योग्य मेमोरी का एक बाइट भी दे सके। प्रत्येक घटक को समझने से पता चलता है कि संख्या वहां क्यों पहुंचती है जहां वह पहुंचती है।

सबसे पहले, ग्लिबैक का मॉलोक मुख्य क्षेत्र को आरंभ करता है - प्राथमिक बहीखाता संरचना जो मुख्य थ्रेड पर सभी आवंटन को ट्रैक करती है। इस क्षेत्र में ढेर के लिए मेटाडेटा, फ्री-लिस्ट पॉइंटर्स और विभिन्न आवंटन आकारों के लिए बिन संरचनाएं शामिल हैं। एलोकेटर sbrk() के माध्यम से प्रोग्राम ब्रेक को बढ़ाता है, और प्रारंभिक एक्सटेंशन M_TOP_PAD नामक एक आंतरिक पैरामीटर द्वारा नियंत्रित होता है, जो 128 KB पैडिंग पर डिफ़ॉल्ट होता है। हालाँकि, वास्तविक प्रारंभिक अनुरोध को पृष्ठ संरेखण और मौजूदा ब्रेक स्थिति के लिए समायोजित किया जाता है, जिसके परिणामस्वरूप अक्सर छोटा पहला अनुरोध होता है - आमतौर पर नए सिरे से शुरू की गई प्रक्रिया पर 72 केबी के आंकड़े के करीब पहुंच जाता है।

💡 क्या आप जानते हैं?

Mewayz एक प्लेटफ़ॉर्म में 8+ बिजनेस टूल्स की जगह लेता है

सीआरएम · इनवॉइसिंग · एचआर · प्रोजेक्ट्स · बुकिंग · ईकॉमर्स · पीओएस · एनालिटिक्स। निःशुल्क सदैव योजना उपलब्ध।

निःशुल्क प्रारंभ करें →

दूसरा, glibc 2.26 के बाद से, एलोकेटर पहले उपयोग पर थ्रेड-लोकल कैश (tcache) को प्रारंभ करता है। Tcache में 64 डिब्बे (छोटे-आवंटन आकार वर्ग के लिए एक) होते हैं, प्रत्येक 7 कैश्ड टुकड़ों को रखने में सक्षम होता है। Tcache_perthread_struct स्वयं लगभग 1 KB की खपत करता है, लेकिन इसे आरंभ करने का कार्य व्यापक क्षेत्र सेटअप को ट्रिगर करता है। तीसरा, C++ रनटाइम ने आपके main() के चलने से पहले ही आवंटन कर दिया है - स्थिर कंस्ट्रक्टर, std::cout और दोस्तों के लिए iostream बफर आरंभीकरण, और लोकेल सेटअप सभी उस प्रारंभिक ढेर पदचिह्न में योगदान करते हैं।

एरेना प्रणाली और पूर्व-आवंटन स्मार्ट क्यों है

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

एक प्रोग्राम पर विचार करें जो आरंभीकरण के दौरान 10,000 छोटे आवंटन करता है। पूर्व-आवंटन के बिना, इसका मतलब 10,000 सिस्टम कॉल होगा, जिसकी लागत लगभग 1-2 मिलीसेकंड शुद्ध ओवरहेड होगी। एक क्षेत्र-आधारित आवंटनकर्ता के साथ, पहला आवंटन ट्रिगर

Build Your Business OS Today

From freelancers to agencies, Mewayz powers 138,000+ businesses with 207 integrated modules. Start free, upgrade when you grow.

Create Free Account →

Frequently Asked Questions

क्या यह 72 KB आवंटन सभी ऑपरेटिंग सिस्टम (Linux, Windows, macOS) पर समान है?

नहीं, यह मान विशेष रूप से Linux पर glibc लाइब्रेरी का एक व्यवहार है। Windows और macOS जैसे अलग-अलग ऑपरेटिंग सिस्टम अलग मेमोरी प्रबंधन रणनीतियों का उपयोग करते हैं और उनका "पहला आवंटन" आकार भिन्न हो सकता है। यह अंतर्निहित सिस्टम लाइब्रेरी (जैसे glibc का malloc) द्वारा प्रबंधित एक प्रारंभिक "हीप" या "मेमोरी पूल" बनाने का परिणाम है।

क्या यह अतिरिक्त मेमोरी वास्तव में बर्बाद हो जाती है?

नहीं बिल्कुल नहीं। यह मेमोर इंटरनल्स के लिए एक सामान्य अनुकूलन है। ऑपरेटिंग सिस्टम से मेमोरी का अनुरोध करना (सिस्टम कॉल के माध्यम से) एक अपेक्षाकृत महंगा ऑपरेशन है। 72 KB का यह प्रारंभिक ब्लॉक भविष्य के छोटे आवंटनों को तेजी से संभालने के लिए एक "कैश" या पूल के रूप में कार्य करता है, जिससे बार-बार सिस्टम कॉल की आवश्यकता समाप्त हो जाती है।

क्या मैं इस व्यवहार को बदल सकता हूं या इस आवंटन से बच सकता हूं?

सीधे तौर पर, एक सामान्य प्रोग्रामर के रूप में नहीं। यह आपकी C++ लाइब्रेरी (जैसे glibc) की एक डिज़ाइन विशेषता है। हालाँकि, आप वैकल्पिक मेमोरी अलोकेटर (जैसे jemalloc या tcmalloc) का उपयोग कर सकते हैं जिनके अलग-अलग प्रारंभिक व्यवहार हो सकते हैं। Mewayz जैसे उन्नत प्रोफाइलिंग टूल (207+ मॉड्यूल के साथ) आपको मेमोरी आवंटन पैटर्न को गहराई से समझने में मदद कर सकते हैं।

अगर मेरा प्रोग्राम बहुत सारे छोटे आवंटन करता है, तो क्या यह 72 KB से आगे बढ़ेगा?

हाँ, बिल्कुल। प्रारंभिक 72 KB ब्लॉक के समाप्त हो जाने पर, मेमोरी अलोकेटर (malloc) ऑपरेटिंग सिस्टम से मेमोरी का एक और, आमतौर पर बड़ा, ब्लॉक अनुरोध करेगा ताकि भविष्य के अनुरोधों को पूरा किया जा सके। यह प्रक्रिया आपके प्रोग्राम की मेमोरी मांग के अनुसार चलती रहती है। Mewayz जैसे टूल आपको यह विज़ुअलाइज़ करने में मदद कर सकते हैं कि आपकी प्रक्रिया का हीप समय के साथ कैसे बढ़ता है।

Mewayz मुफ़्त आज़माएं

सीआरएम, इनवॉइसिंग, प्रोजेक्ट्स, एचआर और अधिक के लिए ऑल-इन-वन प्लेटफॉर्म। कोई क्रेडिट कार्ड आवश्यक नहीं।

आज ही अपने व्यवसाय का प्रबंधन अधिक स्मार्ट तरीके से शुरू करें।

30,000+ व्यवसायों से जुड़ें। सदैव मुफ़्त प्लान · क्रेडिट कार्ड की आवश्यकता नहीं।

क्या यह उपयोगी पाया गया? इसे शेयर करें।

क्या आप इसे व्यवहार में लाने के लिए तैयार हैं?

30,000+ व्यवसायों में शामिल हों जो मेवेज़ का उपयोग कर रहे हैं। सदैव निःशुल्क प्लान — कोई क्रेडिट कार्ड आवश्यक नहीं।

मुफ़्त ट्रायल शुरू करें →

कार्रवाई करने के लिए तैयार हैं?

आज ही अपना मुफ़्त Mewayz ट्रायल शुरू करें

ऑल-इन-वन व्यवसाय प्लेटफॉर्म। क्रेडिट कार्ड की आवश्यकता नहीं।

निःशुल्क प्रारंभ करें →

14-दिन का निःशुल्क ट्रायल · क्रेडिट कार्ड नहीं · कभी भी रद्द करें