एप्लिकेशन-स्तरीय प्रोग्रामर के लिए सैद्धांतिक मॉडल ऐसा लगता है कि ऐसा ऐसा है। असल में, सामान्य स्टार्टअप प्रक्रिया (लिनक्स 1.x में कम से कम, मेरा मानना है कि 2.x और 3.x अनुकूलित लेकिन इसी तरह कर रहे हैं) है:
- गिरी एक प्रक्रिया संदर्भ बनाता है (अधिक या -less, आभासी मशीन)
- है कि इस प्रक्रिया के संदर्भ में, यह एक आभासी स्मृति मानचित्रण है कि आपके निष्पादन योग्य फ़ाइल
- के शुरू करने के रैम पते से नक्शे यह मानते हुए कि आप गतिशील रूप से लिंक किए गए हैं (डिफ़ॉल्ट/सामान्य) को परिभाषित करता है,
ld.so
प्रोग्राम (उदाहरण के लिए /lib/ld-linux.so.2
) आपके प्रोग्राम के शीर्षकों में परिभाषित साझा पुस्तकालयों के लिए मेमोरी मैपिंग सेट करता है
- कर्नेल आपके प्रोग्राम की स्टार्टअप रूटीन में एक
jmp
करता है (सी प्रोग्राम के लिए, यह crtprec80
जैसा कुछ है, जो main
पर कॉल करता है)। चूंकि इसने केवल मैपिंग सेट की है, और वास्तव में किसी भी पेज (*) को लोड नहीं किया है, इसलिए यह सीपीयू की मेमोरी मैनेजमेंट यूनिट से पेज फॉल्ट का कारण बनता है, जो कि कर्नेल में एक बाधा (अपवाद, सिग्नल) है।
- कर्नेल का पृष्ठ फॉल्ट हैंडलर आपके प्रोग्राम के कुछ अनुभाग को लोड करता है, जिसमें भाग शामिल है जो पेज गलती को रैम में लाता है।
- जैसे ही आपका प्रोग्राम चलता है, यदि यह वर्चुअल एड्रेस एक्सेस करता है जिसमें रैम बैकिंग नहीं है, तो पेज दोष आते हैं और कर्नेल को प्रोग्राम को संक्षिप्त रूप से निलंबित करने का कारण बनता है, डिस्क से पृष्ठ लोड करें और फिर कार्यक्रम पर वापसी नियंत्रण।यह सभी "निर्देशों के बीच" होता है और आमतौर पर ज्ञानी नहीं होता है।
- जैसा कि आप
malloc
/new
का उपयोग करते हैं, कर्नेल रैम के पढ़ने-लिखने वाले पृष्ठ (डिस्क बैकिंग फ़ाइलों के बिना) बनाता है और उन्हें आपके वर्चुअल एड्रेस स्पेस में जोड़ता है।
- यदि आप वर्चुअल मेमोरी मैपिंग में सेट अप मेमोरी स्थान तक पहुंचने का प्रयास करके पेज फॉल्ट फेंकते हैं, तो आपको एक सेगमेंटेशन उल्लंघन उल्लंघन (SIGSEGV) मिलता है, जो आमतौर पर घातक होता है।
- चूंकि सिस्टम भौतिक RAM से बाहर चला जाता है, रैम के पृष्ठ हटा दिए जाते हैं; अगर वे डिस्क पर पहले से ही कुछ की केवल पढ़ने की प्रतियां हैं (जैसे निष्पादन योग्य, या साझा ऑब्जेक्ट फ़ाइल), तो उन्हें केवल डी-आवंटित किया जाता है और उन्हें उनके स्रोत से पुनः लोड किया जाता है; अगर वे पढ़े गए हैं (जैसे स्मृति "
malloc
का उपयोग करके" बनाई गई "), वे पृष्ठ फ़ाइल = स्वैप फ़ाइल = स्वैप विभाजन = ऑन-डिस्क वर्चुअल मेमोरी) पर लिखे गए हैं। इन "मुक्त" पृष्ठों तक पहुंचने से एक और पेज फॉल्ट होता है, और वे फिर से लोड हो जाते हैं।
आम तौर पर, हालांकि, जब तक आपकी प्रक्रिया उपलब्ध रैम से बड़ी नहीं होती है - और डेटा निष्पादन योग्य से लगभग हमेशा बड़ा होता है - आप सुरक्षित रूप से दिखा सकते हैं कि आप दुनिया में अकेले हैं और इनमें से कोई भी मांग पेजिंग सामग्री नहीं है हो रहा।
तो: प्रभावी रूप से, कर्नेल पहले से ही लोड होने के दौरान आपके प्रोग्राम को चला रहा है (और कभी भी कुछ पेज लोड नहीं कर सकता है, अगर आप कभी भी उस कोड में कूद नहीं जाते हैं/उस डेटा को संदर्भित करते हैं)।
यदि आपका स्टार्टअप विशेष रूप से सुस्त है, तो आप साझा लाइब्रेरी लोड को अनुकूलित करने के लिए prelink
सिस्टम देख सकते हैं। इससे ld.so
को स्टार्टअप पर (exec
और प्रोग्राम के कॉलिंग के साथ-साथ जब आप पहली बार लाइब्रेरी रूटीन कॉल करते हैं) के काम को कम कर देता है।
कभी कभी, स्थिर जोड़ने के लिए एक कार्यक्रम के प्रदर्शन में सुधार कर सकते हैं लेकिन राम का एक प्रमुख कीमत पर - के बाद से अपने पुस्तकालयों साझा नहीं किया जाता है, तो आप डुप्लिकेट बना रहे हैं "अपने libc
" साझा libc
के साथ ही उस हर दूसरे कार्यक्रम है उदाहरण के लिए, का उपयोग कर। यह आम तौर पर केवल एम्बेडेड सिस्टम में उपयोगी होता है जहां आपका प्रोग्राम मशीन पर अकेले या कम अकेले चल रहा है।
(*) असल में, कर्नेल थोड़ा होशियार है, और आम तौर पर कुछ पृष्ठों प्रीलोड पेज दोष की संख्या को कम करने के लिए होगा, लेकिन सिद्धांत अनुकूलन के ही है, भले ही
ओएस सामान्य रूप से इस तरह से एक सौहार्दपूर्ण तरीके से संबंधित है। –
100 एमबी बाइनरी असंभव है? मेरे यहां एकमात्र 500 एलओसी, भारी टेम्पलेट और बूस्टेड सी ++ प्रोग्राम से संकलित 6 एमबी बाइनरी है। मैं शर्त लगाता हूं कि मैं बिना किसी परेशानी के 100 एमबी तक पहुंच सकता हूं। –
कुछ भी असंभव नहीं है! बस एक ग्रहण ग्रहण डेवलपर के संपर्क में रहें, वे आपको सभी चालें सिखाएंगे। – Lundin