नोट: मैं मान सकता हूं कि आपकी मशीन में मेमोरी मैपिंग यूनिट (MMU) है। एक Linux संस्करण (isClinux) है जिसे MMU की आवश्यकता नहीं है, और यह उत्तर वहां लागू नहीं होता है।
MMU क्या है? यह प्रोसेसर और / या मेमोरी कंट्रोलर का हार्डवेयर- पार्ट है। साझा लाइब्रेरी को समझना आपको यह समझने की आवश्यकता नहीं है कि एमएमयू कैसे काम करता है, बस यह कि एमएमयू तार्किक मेमोरी एड्रेस (कार्यक्रमों द्वारा उपयोग किए जाने वाले) और भौतिक के बीच अंतर करने की अनुमति देता हैमेमोरी एड्रेस (वास्तव में मेमोरी बस में मौजूद हैं)। मेमोरी को पृष्ठों में तोड़ दिया जाता है, आमतौर पर लिनक्स पर आकार में 4K। 4k पृष्ठों के साथ, तार्किक पते 0–4095 पृष्ठ 0 हैं, तार्किक पते 4096–8191 पृष्ठ 1 हैं, आदि। MMU उन RAM के भौतिक पृष्ठों को मैप करते हैं, और प्रत्येक तार्किक पृष्ठ को आमतौर पर 0 या 1 भौतिक पृष्ठों पर मैप किया जा सकता है। एक दिया गया भौतिक पृष्ठ कई तार्किक पृष्ठों के अनुरूप हो सकता है (यह है कि मेमोरी कैसे साझा की जाती है: कई तार्किक पृष्ठ एक ही भौतिक पृष्ठ के अनुरूप हैं)। ध्यान दें कि यह ओएस की परवाह किए बिना लागू होता है; यह हार्डवेयर का विवरण है।
प्रक्रिया स्विच पर, कर्नेल MMU पृष्ठ मैपिंग को बदलता है, ताकि प्रत्येक प्रक्रिया का अपना स्थान हो। पता 4096 प्रक्रिया में 1000 हो सकता है (और आमतौर पर) प्रक्रिया 1001 में पते 4096 से पूरी तरह से अलग है।
जब भी आप किसी पते को देखते हैं, तो यह एक तार्किक पता है। उपयोगकर्ता अंतरिक्ष कार्यक्रम शायद ही कभी शारीरिक पतों से निपटते हैं।
अब, पुस्तकालयों के निर्माण के भी कई तरीके हैं। मान लीजिए कि कोई प्रोग्राम foo()
लाइब्रेरी में फ़ंक्शन को कॉल करता है। सीपीयू प्रतीकों के बारे में कुछ भी नहीं जानता है, या फ़ंक्शन कॉल वास्तव में करता है - यह सिर्फ एक तार्किक पते पर कूदना जानता है, और जो भी कोड वहां मिलता है उसे निष्पादित करता है। कुछ तरीके हैं जो यह कर सकते हैं (और इसी तरह की चीजें तब लागू होती हैं जब एक पुस्तकालय अपने स्वयं के वैश्विक डेटा तक पहुंचता है, आदि):
- इसे कॉल करने के लिए कुछ लॉजिकल एड्रेस को हार्ड-कोड कर सकते हैं। इसके लिए आवश्यक है कि लाइब्रेरी को हमेशा उसी तार्किक पते पर लोड किया जाए। यदि दो पुस्तकालयों को समान पते की आवश्यकता होती है, तो डायनेमिक लिंकिंग विफल हो जाती है और आप प्रोग्राम लॉन्च नहीं कर सकते। पुस्तकालयों को अन्य पुस्तकालयों की आवश्यकता हो सकती है, इसलिए मूल रूप से इस प्रणाली के प्रत्येक पुस्तकालय के लिए अद्वितीय तार्किक पते होने चाहिए। यह बहुत तेज़ है, हालांकि, अगर यह काम करता है। (यह है कि कैसे चीजों के बारे में किया गया था, और उस तरह का सेट जो प्रीलिंकिंग करता है, सॉर्ट करता है)।
- यह एक नकली तार्किक पते को हार्ड-कोड कर सकता है, और लाइब्रेरी को लोड करते समय डायनेमिक लिंकर को उचित एक में संपादित करने के लिए कह सकता है। यह पुस्तकालयों को लोड करते समय बहुत कम समय खर्च करता है, लेकिन इसके बाद यह बहुत तेज होता है।
- यह अप्रत्यक्ष की एक परत जोड़ सकता है: लाइब्रेरी को लोड किए जाने वाले तार्किक पते को होल्ड करने के लिए सीपीयू रजिस्टर का उपयोग करें , और फिर उस रजिस्टर से ऑफसेट के रूप में सब कुछ एक्सेस करें। यह प्रत्येक एक्सेस पर एक प्रदर्शन लागत लगाता है।
बहुत ज्यादा कोई भी # 1 का उपयोग नहीं करता है, कम से कम सामान्य-उद्देश्य प्रणालियों पर नहीं। उस अद्वितीय तार्किक पता सूची को रखना 32-बिट सिस्टम (चारों ओर जाने के लिए पर्याप्त नहीं है) और 64-बिट सिस्टम पर एक प्रशासनिक दुःस्वप्न पर असंभव है। प्री-लिंकिंग सॉर्ट ऐसा करता है, हालांकि, प्रति-प्रणाली के आधार पर।
क्या # 2 या # 3 का उपयोग किया जाता है यह निर्भर करता है कि लाइब्रेरी को GCC -fPIC
(स्थिति स्वतंत्र कोड) विकल्प के साथ बनाया गया था या नहीं । # 2 बिना है, # 3 साथ है। आमतौर पर, पुस्तकालयों के साथ बनाया जाता है -fPIC
, इसलिए # 3 क्या होता है।
अधिक जानकारी के लिए, Ulrich Drepper की हाउ टू राइट टू शेयर्ड लाइब्रेरीज़ (PDF) देखें ।
तो, अंत में, आपके प्रश्न का उत्तर दिया जा सकता है:
- यदि पुस्तकालय के साथ बनाया गया है
-fPIC
(जैसा कि यह लगभग निश्चित रूप से होना चाहिए), पृष्ठों का विशाल बहुमत हर प्रक्रिया के लिए बिल्कुल समान है जो इसे लोड करता है। आपकी प्रक्रियाएँ a
और b
पुस्तकालय विभिन्न तार्किक पतों पर अच्छी तरह लोड हो सकते हैं, लेकिन वे एक ही भौतिक पृष्ठों की ओर संकेत करेंगे: स्मृति साझा की जाएगी। इसके अलावा, रैम में डेटा डिस्क पर क्या होता है, इसके साथ मेल खाता है, इसलिए इसे केवल पृष्ठ दोष हैंडलर द्वारा आवश्यक होने पर लोड किया जा सकता है।
- यदि पुस्तकालय के बिना बनाया गया है
-fPIC
, तो यह पता चला है कि पुस्तकालय के अधिकांश पृष्ठों को लिंक संपादन की आवश्यकता होगी, और अलग होगा। इसलिए, उन्हें अलग-अलग भौतिक पृष्ठ होने चाहिए (क्योंकि उनमें अलग-अलग डेटा होते हैं)। इसका मतलब है कि वे साझा नहीं हैं। पृष्ठों का मिलान डिस्क पर नहीं होता है, इसलिए मुझे आश्चर्य नहीं होगा यदि पूरी लाइब्रेरी लोड हो गई है। यह निश्चित रूप से बाद में डिस्क (स्वैप में) तक स्वैप किया जा सकता है।
आप pmap
टूल के साथ या सीधे विभिन्न फ़ाइलों की जाँच करके इसकी जांच कर सकते हैं /proc
। उदाहरण के लिए, यहां pmap -x
दो अलग-अलग नव-स्पंदित bc
एस पर (आंशिक) आउटपुट है । ध्यान दें कि pmap द्वारा दिखाए गए पते विशिष्ट, तार्किक पते के रूप में हैं:
pmap -x 14739
Address Kbytes RSS Dirty Mode Mapping
00007f81803ac000 244 176 0 r-x-- libreadline.so.6.2
00007f81803e9000 2048 0 0 ----- libreadline.so.6.2
00007f81805e9000 8 8 8 r---- libreadline.so.6.2
00007f81805eb000 24 24 24 rw--- libreadline.so.6.2
pmap -x 17739
Address Kbytes RSS Dirty Mode Mapping
00007f784dc77000 244 176 0 r-x-- libreadline.so.6.2
00007f784dcb4000 2048 0 0 ----- libreadline.so.6.2
00007f784deb4000 8 8 8 r---- libreadline.so.6.2
00007f784deb6000 24 24 24 rw--- libreadline.so.6.2
आप देख सकते हैं कि पुस्तकालय कई हिस्सों में भरा हुआ है, और pmap -x
आपको प्रत्येक पर अलग से विवरण देता है। आप देखेंगे कि दो प्रक्रियाओं के बीच तार्किक पते अलग-अलग हैं; आप यथोचित उम्मीद करते हैं कि वे एक ही हो (चूंकि एक ही कार्यक्रम चल रहा है, और कंप्यूटर आमतौर पर उसी तरह अनुमानित हैं), लेकिन एक सुरक्षा सुविधा है जिसे एड्रेस स्पेस लेआउट रैंडमाइजेशन कहा जाता है जो जानबूझकर उन्हें यादृच्छिक बनाता है।
आप आकार (Kbytes) और निवासी आकार (RSS) के अंतर से देख सकते हैं कि पूरे पुस्तकालय खंड को लोड नहीं किया गया है। अंत में, आप देख सकते हैं कि बड़े मैपिंग के लिए, गंदा 0 है, जिसका अर्थ है कि यह डिस्क पर वास्तव में मेल खाता है।
आप के साथ फिर से चला सकते हैं pmap -XX
, और यह आपको दिखाएगा- आप जिस कर्नेल संस्करण पर चल रहे हैं, उसके आधार पर -XX आउटपुट कर्नेल संस्करण से भिन्न होता है - जिसमें पहली मैपिंग में Shared_Clean
176 होती है, जो वास्तव में मेल खाती है RSS
। Shared
मेमोरी का मतलब है कि भौतिक पेज कई प्रक्रियाओं के बीच साझा किए जाते हैं, और चूंकि यह आरएसएस से मेल खाता है, इसका मतलब है कि सभी पुस्तकालय जो स्मृति में हैं, साझा किए गए हैं (साझा बनाम निजी के आगे स्पष्टीकरण के लिए नीचे देखें):
pmap -XX 17739
Address Perm Offset Device Inode Size Rss Pss Shared_Clean Shared_Dirty Private_Clean Private_Dirty Referenced Anonymous AnonHugePages Swap KernelPageSize MMUPageSize Locked VmFlagsMapping
7f784dc77000 r-xp 00000000 fd:00 1837043 244 176 19 176 0 0 0 176 0 0 0 4 4 0 rd ex mr mw me sd libreadline.so.6.2
7f784dcb4000 ---p 0003d000 fd:00 1837043 2048 0 0 0 0 0 0 0 0 0 0 4 4 0 mr mw me sd libreadline.so.6.2
7f784deb4000 r--p 0003d000 fd:00 1837043 8 8 8 0 0 0 8 8 8 0 0 4 4 0 rd mr mw me ac sd libreadline.so.6.2
7f784deb6000 rw-p 0003f000 fd:00 1837043 24 24 24 0 0 0 24 24 24 0 0 4 4 0 rd wr mr mw me ac sd libreadline.so.6.2
यह भी देखें
-fPIC
उपयोग कुछ समय पहले पूरी तरह बदल गया है)?