मेरा सवाल यह है कि क्या उन पुस्तकालयों में कोड मुख्य आवेदन के समान हीप में स्मृति आवंटित करेगा या क्या वे अपने ही ढेर का उपयोग करेंगे?
पुस्तकालय आवेदन (glibc
से उदा) के रूप में ही malloc/free
का उपयोग करता है - तो हाँ, कार्यक्रम और सभी पुस्तकालयों एकल ढेर का उपयोग करेगा।
पुस्तकालय mmap
सीधे का उपयोग करता है, यह स्मृति जो कार्यक्रम में ही द्वारा प्रयुक्त स्मृति नहीं है आवंटित कर सकते हैं।
तो उदाहरण के लिए, .so फ़ाइल में कुछ फ़ंक्शन malloc को कॉल करता है, क्या यह उसी हीप मैनेजर को एप्लिकेशन या किसी अन्य के रूप में उपयोग करेगा?
यदि .so कॉल मॉलोक से कार्य करता है, तो यह मॉलोक प्रोग्राम से बुलाए गए मॉलोक जैसा ही है। आप ढेर प्रबंधकों की
LD_DEBUG=bindings ./your_program
हाँ, कई उदाहरण (डिफ़ॉल्ट विन्यास के साथ) के साथ/glibc (> 2.1) लिनक्स में लॉग बाध्यकारी प्रतीक देख सकते हैं (समस्या के साथ है एक दूसरे के बारे जानने के बिना नहीं साथ नहीं हो सकते उदाहरण के बीच सिंक्रनाइज़ किए गए ब्रैक-आवंटित ढेर आकार को रखते हुए)। लेकिन एक कॉन्फ़िगरेशन संभव है जब कई उदाहरण सह-अस्तित्व में हो सकते हैं।
अधिकांश क्लासिक मॉलोक कार्यान्वयन (ptmalloc *, dlmalloc, आदि) सिस्टम से स्मृति प्राप्त करने के दो तरीकों का उपयोग कर सकते हैं: brk
और mmap
। ब्रैक क्लासिक ढेर है, जो रैखिक है और बढ़ सकता है या सिकुड़ सकता है। एमएमएपी कहीं भी बहुत मेमोरी प्राप्त करने की अनुमति देता है; और आप किसी भी क्रम में इस स्मृति को सिस्टम (इसे मुक्त) पर वापस कर सकते हैं।
जब malloc builded है, नि: विधि निष्क्रिय किया जा सकता। फिर malloc केवल mmap
एस का उपयोग करके रैखिक ढेर का अनुकरण करेगा या यहां तक कि क्लासिक रैखिक ढेर को अक्षम कर देगा और सभी आवंटन को असम्बद्ध mmaped fragmens से बनाया जाएगा।
तो, कुछ पुस्तकालय में अपना मेमोरी मैनेजर हो सकता है, उदा। brk
के साथ संकलित या गैर-मॉलोक मेमोरी मैनेजर के साथ संकलित। यह प्रबंधक उदाहरण के लिए, malloc
और free
के अलावा अन्य समारोह के नाम होना चाहिए malloc1
और free1
या/निर्यात गतिशील लिंकर को यह नाम नहीं दिखाने के लिए करना चाहिए।
साथ ही, उन साझा यादों में वैश्विक डेटा के बारे में क्या। यह कहां झूठ बोलता है?मैं उस एप्लिकेशन के बारे में जानता हूं जो बीएसएस और डेटा सेगमेंट में है, लेकिन यह नहीं पता कि यह उन साझा ऑब्जेक्ट फ़ाइलों के लिए कहां है।
आपको प्रोग्राम के बारे में सोचना चाहिए और साथ ही ईएलएफ फाइलों के बारे में भी सोचना चाहिए। प्रत्येक ईएलएफ फ़ाइल में "प्रोग्राम हेडर" (readelf -l elf_file
) है। ईएलएफ से मेमोरी में डेटा लोड करने का तरीका प्रोग्राम हेडर के प्रकार पर निर्भर करता है। यदि प्रकार "LOAD
" है, तो फ़ाइल का संबंधित भाग निजी रूप से mmap
ed (Sic!) स्मृति में होगा। आमतौर पर, 2 लोड सेगमेंट होते हैं; आर + एक्स (पढ़ें + निष्पादित) झंडे के साथ कोड के लिए पहला और दूसरा आर + डब्ल्यू (पढ़ें + लिखें) झंडे वाले डेटा के लिए है। .bss
और .data
(वैश्विक डेटा) अनुभाग दोनों लिखें सक्षम ध्वज के साथ लोड लोड के खंड में रखा गया है।
दोनों निष्पादन योग्य और साझा लाइब्रेरी में लोड सेगमेंट हैं। कुछ खंडों में memory_size> file_size है। इसका मतलब है कि खंड स्मृति में विस्तारित किया जाएगा; यह के पहले भाग, ELF फ़ाइल, और आकार (memory_size-FILE_SIZE) के दूसरे भाग से डेटा शून्य (*bss
के लिए वर्गों) से भर दिया जाएगा से भर दिया जाएगा mmap(/dev/zero)
और memset(0)
जब कर्नेल या गतिशील लिंकर भार ELF का उपयोग कर स्मृति में फ़ाइल, वे साझा करने के बारे में नहीं सोचेंगे। उदाहरण के लिए, आप दो बार एक ही प्रोग्राम शुरू करना चाहते हैं। पहली प्रक्रिया एमएलएपी के साथ ईएलएफ फाइल के केवल पढ़ने के हिस्से को लोड करेगी; दूसरी प्रक्रिया एक ही एमएमएपी करेगी (यदि एएसएलआर सक्रिय है - दूसरा एमएमएपी अलग वर्चुअल एड्रेस में होगा)। यह भौतिक मेमोरी में डेटा की एक प्रतिलिपि रखने के लिए पेज कैश (वीएफएस उपप्रणाली) का कार्य है (COPY-on-WRITE उर्फ गाय के साथ); और mmap बस प्रत्येक प्रक्रिया में वर्चुअल एड्रेस से मैपिंग्स को एक भौतिक स्थान में सेट करेगा। अगर कोई प्रक्रिया मेमोरी पेज बदल देगी; यह अद्वितीय निजी भौतिक स्मृति के लिए लिखने पर प्रतिलिपि बनाई जाएगी।
लोड हो रहा है कोड glibc/elf/dl-load.c
(_dl_map_object_from_fd
) ld.so के लिए और linux-kernel/fs/binfmt_elf.c
में कर्नेल के ELF लोडर (elf_map
, load_elf_binary
) के लिए है। PT_LOAD
के लिए एक खोज करें।
तो, वैश्विक डेटा और बीएसएस डेटा हमेशा प्रत्येक प्रक्रिया में निजी रूप से मिमी किया जाता है, और वे गाय से संरक्षित होते हैं।
ढेर और ढेर brk की तरह प्रक्रिया (मुख्य थ्रेड के ढेर के लिए) में नि: + mmap (ढेर) के साथ और पूर्ण रूप से अपने ओएस कर्नेल द्वारा चलाने के समय में आवंटित किए जाते हैं। अतिरिक्त थ्रेड के ढेर mmap
pthread_create
में आवंटित किए जाते हैं।
क्या आप पूछ रहे हैं कि साझा लाइब्रेरी के अनुभाग मूल निष्पादन योग्य वर्गों के साथ गतिशील लिंकिंग के साथ एकत्र किए गए हैं या नहीं? –
साझा लाइब्रेरी बीएसएस और डेटा सेगमेंट कुछ शेष एप्लिकेशन के बीएसएस और डेटा सेगमेंट को अलग कर देंगे, लेकिन यह सब आपके लिए सिस्टम द्वारा संभाला जाता है। –