उन भाषाओं में कचरा संग्रह कैसे काम करता है जो मूल रूप से संकलित हैं?


79

कई उत्तर एक स्टैक ओवरफ्लो ब्राउज़ करने के बाद, यह स्पष्ट है कि कुछ मूल रूप से संकलित भाषाओं में कचरा संग्रह है । लेकिन यह मेरे लिए स्पष्ट नहीं है कि यह वास्तव में कैसे काम करेगा।

मैं समझता हूं कि एक स्पष्ट भाषा के साथ कचरा संग्रह कैसे काम कर सकता है। कचरा संग्रहकर्ता दुभाषिया के साथ बस चलाएगा और प्रोग्राम की मेमोरी से अप्रयुक्त और अगम्य वस्तुओं को हटा देगा। वे दोनों साथ-साथ चल रहे हैं।

हालांकि संकलित भाषाओं के साथ यह कैसे काम करेगा? मेरी समझ यह है कि एक बार संकलक ने स्रोत कोड को लक्ष्य कोड - विशेष रूप से देशी मशीन कोड - में संकलित किया है। इसका काम समाप्त हो गया है। तो कैसे संकलित कार्यक्रम कचरा एकत्र किया जा सकता है?

क्या कम्पाइलर किसी तरह से सीपीयू के साथ काम करता है जबकि "कचरा" ऑब्जेक्ट को हटाने के लिए प्रोग्राम निष्पादित किया जाता है? या संकलक प्रोग्राम के निष्पादन योग्य में कुछ न्यूनतम कचरा कलेक्टर शामिल करता है।

मेरा मानना ​​है कि स्टैक ओवरफ्लो पर इस उत्तर से इस अंश के कारण मेरे बाद के बयान में पूर्व की तुलना में अधिक वैधता होगी :

ऐसी ही एक प्रोग्रामिंग लैंग्वेज है एफिल। अधिकांश एफिल कम्पाइलर पोर्टेबिलिटी कारणों के लिए सी कोड उत्पन्न करते हैं। यह C कोड मानक C कंपाइलर द्वारा मशीन कोड का उत्पादन करने के लिए उपयोग किया जाता है। एफिल कार्यान्वयन इस संकलित कोड के लिए जीसी (और कभी-कभी सटीक जीसी) भी प्रदान करता है, और वीएम की कोई आवश्यकता नहीं है। विशेष रूप से, VisualEiffel संकलक ने पूर्ण जीसी समर्थन के साथ सीधे देशी x86 मशीन कोड उत्पन्न किया

अंतिम कथन का अर्थ यह प्रतीत होता है कि संकलक में अंतिम निष्पादक में कुछ कार्यक्रम शामिल है जो कचरा संग्राहक के रूप में कार्य करता है जबकि कार्यक्रम चल रहा है।

कचरा संग्रह के बारे में डी भाषा की वेबसाइट पर पेज - जो मूल रूप से संकलित है और इसमें एक वैकल्पिक कचरा संग्रहकर्ता है - यह भी संकेत देता है कि कचरा संग्रह को लागू करने के लिए कुछ पृष्ठभूमि कार्यक्रम मूल निष्पादन कार्यक्रम के साथ चलता है।

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

यदि ऊपर वर्णित विधि का उपयोग किया जाता है, तो यह वास्तव में कैसे काम करेगा? संकलक कुछ कचरा संग्रह कार्यक्रम की एक प्रति संग्रहीत करता है और इसे प्रत्येक निष्पादन योग्य में पेस्ट करता है जो इसे उत्पन्न करता है?

या मैं अपनी सोच में दोषपूर्ण हूं? यदि हां, तो संकलित भाषाओं के लिए कचरा संग्रह को लागू करने के लिए किन तरीकों का उपयोग किया जाता है और वे वास्तव में कैसे काम करेंगे?


1
अगर इस सवाल का करीबी मतदाता यह बता सकता है कि क्या गलत है, तो मैं इसे ठीक कर सकता हूं, तो मैं इसकी सराहना करूंगा।
क्रिश्चियन डीन

6
यदि आप इस तथ्य को स्वीकार करते हैं कि जीसी मूल रूप से एक विशेष प्रोग्रामिंग भाषा कार्यान्वयन के लिए आवश्यक पुस्तकालय का हिस्सा है, तो आपके प्रश्न के जीसी को प्रति जीसी और सब कुछ स्थिर बनाम गतिशील लिंकिंग के साथ कुछ नहीं करना है ।
थियोडोरोस चटजिआनियाकिंस

7
आप कचरा संग्रहकर्ता को रनटाइम लाइब्रेरी का हिस्सा मान सकते हैं जो भाषा के समकक्ष लागू करता है malloc()
बमर

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

1
GC डायनामिक मेमोरी की एक विशेषता है, दुभाषिया की विशेषता नहीं।
दिमित्री ग्रिगोरीव

जवाबों:


52

संकलित भाषा में कचरा संग्रह उसी तरह से काम करता है जैसे कि एक व्याख्या की गई भाषा में। गो जैसी भाषाएं कचरा संग्रह करने वालों का उपयोग करती हैं, भले ही उनका कोड आमतौर पर मशीन कोड से आगे के समय के लिए संकलित किया जाता है।

(ट्रेसिंग) कचरा संग्रह आम तौर पर वर्तमान में चल रहे सभी थ्रेड्स के कॉल स्टैक को चलाकर शुरू होता है। उन ढेर पर वस्तुएं हमेशा जीवित रहती हैं। उसके बाद, कचरा संग्रहकर्ता उन सभी वस्तुओं का पता लगाता है जो जीवित वस्तुओं द्वारा इंगित की जाती हैं, जब तक कि संपूर्ण लाइव ऑब्जेक्ट ग्राफ की खोज नहीं की जाती है।

यह स्पष्ट है कि ऐसा करने के लिए अतिरिक्त जानकारी की आवश्यकता होती है जो C जैसी भाषाएं प्रदान नहीं करती हैं। विशेष रूप से, इसमें प्रत्येक फ़ंक्शन के स्टैक फ्रेम के नक्शे की आवश्यकता होती है जिसमें सभी पॉइंटर्स (और शायद उनके डेटाैटिप्स) के साथ-साथ सभी ऑब्जेक्ट लेआउट के नक्शे होते हैं जिसमें समान जानकारी होती है।

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

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


9
उपयोगिता पुस्तकालयों और JIT संकलन के बीच, "मूल के लिए संकलित" और "एक रनटाइम वातावरण में चलता है" के बीच की रेखाएं अधिक से अधिक धुंधली हो रही हैं।
corsiKa

6
बस उन भाषाओं के बारे में थोड़ा जोड़ने के लिए जो जीसी समर्थन के साथ नहीं आती हैं: यह सच है कि सी और अन्य ऐसी भाषाएं कॉल स्टैक के बारे में जानकारी प्रदान नहीं करती हैं, लेकिन यदि आप कुछ प्लेटफ़ॉर्म-विशिष्ट कोड (आमतौर पर थोड़ा सहित) के साथ ठीक हैं असेंबली कोड का) "रूढ़िवादी कचरा संग्रह" को लागू करना अभी भी संभव है। बोहम जीसी इस वास्तविक जीवन कार्यक्रमों में इस्तेमाल का एक उदाहरण है।
मत्ती वीरकुंन

2
@ कोर्सीका या यों कहें कि रेखा बहुत अधिक विशिष्ट है। अब हम देखते हैं कि वे अलग-अलग असंबंधित अवधारणाएँ हैं, और प्रत्येक अभिभावक के विलोम नहीं।
क्रॉल्टन

4
एक अतिरिक्त जटिलता जिसे आपको संकलित बनाम व्याख्या किए गए रनटाइम्स के बारे में पता होना चाहिए, वह आपके उत्तर में इस वाक्य से संबंधित है: "(अनुरेखण) कचरा संग्रह आमतौर पर उन सभी थ्रेड्स के कॉल स्टैक पर चलने से शुरू होता है जो वर्तमान में चल रहे हैं।" संकलित वातावरण में जीसी को लागू करने का मेरा अनुभव यह है कि ढेर का पता लगाना पर्याप्त नहीं है। प्रारंभिक बिंदु आमतौर पर थ्रेड्स को उनके रजिस्टरों से ट्रेस करने के लिए लंबे समय तक निलंबित कर रहा है , क्योंकि उनके पास उन रजिस्टरों में संदर्भ हो सकते हैं जो अभी तक स्टैक में संग्रहीत नहीं किए गए हैं। एक दुभाषिया के लिए, यह आमतौर पर नहीं है ...
जूल्स

... एक समस्या है, क्योंकि पर्यावरण जीसी के लिए "सुरक्षित बिंदुओं" पर जगह ले सकता है जहां दुभाषिया जानता है कि सभी डेटा सुरक्षित रूप से व्याख्या किए गए ढेर में संग्रहीत हैं।
जूल्स

123

क्या कंपाइलर कुछ कचरा संग्रह कार्यक्रम की एक प्रति संग्रहीत करता है और इसे प्रत्येक निष्पादन योग्य में पेस्ट करता है जो यह उत्पन्न करता है?

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


51
@ChristianDean ध्यान दें कि C में एक रनटाइम लाइब्रेरी भी है। जबकि इसमें GC नहीं है, फिर भी यह उस रनटाइम लाइब्रेरी के माध्यम से मेमोरी प्रबंधन करता है: malloc()और free()भाषा के लिए निर्मित नहीं हैं, ऑपरेटिंग सिस्टम का हिस्सा नहीं हैं, लेकिन इस लाइब्रेरी में फ़ंक्शन हैं। सी ++ को कभी-कभी एक कचरा संग्रह पुस्तकालय के साथ भी संकलित किया जाता है, भले ही भाषा को जीसी को ध्यान में रखकर डिजाइन नहीं किया गया हो।
आमोन

18
C ++ में एक रनटाइम लाइब्रेरी भी है जो मेक dynamic_castऔर अपवाद जैसी चीजें काम करती है, भले ही आप जीसी नहीं जोड़ते हों।
सेबेस्टियन रेडल

23
रनटाइम लाइब्रेरी को आवश्यक रूप से प्रत्येक निष्पादन योग्य (जिसे स्टेटिक लिंकिंग कहा जाता है) में कॉपी नहीं किया जाता है, इसे केवल संदर्भित किया जा सकता है (लाइब्रेरी वाले बाइनरी के लिए एक पथ) और निष्पादन समय पर एक्सेस किया जाता है: यह डायनेमिक लिंकिंग है।
मौविसील

16
कंपाइलर को आपके प्रोग्राम के एंट्रीपॉइंट में बिना किसी और चीज के सीधे कूदने की भी आवश्यकता नहीं है। मैं एक शिक्षित अनुमान लगा रहा हूं कि हर कंपाइलर वास्तव में कॉल करने से पहले प्लेटफ़ॉर्म-विशिष्ट आरंभीकरण कोड का एक गुच्छा सम्मिलित करता है main(), और यह पूरी तरह से कानूनी है, कहते हैं, इस कोड में जीसी थ्रेड को आग लगा दें। (मान लें कि GC स्मृति आबंटन कॉल के अंदर नहीं किया गया है।) रनटाइम के समय, GC को वास्तव में यह जानने की आवश्यकता होती है कि ऑब्जेक्ट के कौन से हिस्से पॉइंटर्स या ऑब्जेक्ट रेफरेंस हैं, और कंपाइलर को किसी पॉइंटर रेफरेंस में ऑब्जेक्ट रेफरेंस को ट्रांसलेट करने के लिए कोड का उत्सर्जन करना होगा। यदि GC वस्तुओं को स्थानांतरित करता है।
मिलिमोस

15
@millimoose: हाँ। उदाहरण के लिए, जीसीसी पर, कोड के इस टुकड़े है crt0.o(जो "के लिए खड़ा है सी आर संयुक्त राष्ट्र टी है, जो हर कार्यक्रम (या कम से कम हर प्रोग्राम है जो नहीं है के साथ जुड़ा हुआ हो जाता है IME, बहुत मूल बातें") मुफ्त से चली आ रही )।
जोर्ग डब्ल्यू मित्तग

58

या संकलित प्रोग्राम के कोड में संकलक में कुछ न्यूनतम कचरा कलेक्टर शामिल हैं।

यह कहने का एक अजीब तरीका है "संकलक कार्यक्रम को एक पुस्तकालय के साथ जोड़ता है जो कचरा संग्रह करता है"। लेकिन हां, यही हो रहा है।

यह कुछ खास नहीं है: संकलक आमतौर पर पुस्तकालयों के टन को उन कार्यक्रमों में लिंक करते हैं जिन्हें वे संकलित करते हैं; अन्यथा संकलित कार्यक्रम खरोंच से कई चीजों को फिर से लागू किए बिना बहुत कुछ नहीं कर सकते थे: यहां तक ​​कि स्क्रीन पर पाठ लिखना / एक फ़ाइल / ... के लिए एक पुस्तकालय की आवश्यकता होती है।

लेकिन शायद जीसी इन अन्य पुस्तकालयों से अलग है, जो स्पष्ट एपीआई प्रदान करते हैं जो उपयोगकर्ता कॉल करता है?

नहीं: अधिकांश भाषाओं में, रनटाइम लाइब्रेरी जीसी से परे, सार्वजनिक-सामना वाले एपीआई के बिना बहुत पीछे के काम करते हैं। इन तीन उदाहरणों पर विचार करें:

  1. अपवाद प्रचार और स्टैक अनइंडिंग / विध्वंसक कॉलिंग।
  2. डायनामिक मेमोरी एलोकेशन (जो आमतौर पर किसी फ़ंक्शन को नहीं बुला रहा है, जैसा कि C में है, तब भी जब कोई कचरा संग्रह न हो)।
  3. गतिशील प्रकार की जानकारी (जातियों आदि के लिए) की ट्रैकिंग।

तो एक कचरा संग्रह पुस्तकालय सभी विशेष पर नहीं है, और एक प्राथमिकताओं का इस बात से कोई लेना-देना नहीं है कि किसी कार्यक्रम को समय से पहले संकलित किया गया था या नहीं।


इससे बने बिंदुओं पर कुछ भी पर्याप्त नहीं लगता है और 3 घंटे पहले पोस्ट किए गए शीर्ष उत्तर में समझाया गया है
gnat

11
@ मुझे लगा कि यह उपयोगी / आवश्यक है क्योंकि शीर्ष उत्तर अभी तक पर्याप्त मजबूत नहीं है: यह समान तथ्यों का उल्लेख करता है, लेकिन यह इंगित करने में विफल रहता है कि कचरा संग्रह को एकल करना पूरी तरह से कृत्रिम अंतर है। मौलिक रूप से, ओपी की धारणा त्रुटिपूर्ण है, और शीर्ष उत्तर में इसका उल्लेख नहीं है। मेरा करता है (जबकि "दोषपूर्ण" शब्द के बजाय)
कोनराड रूडोल्फ

यह सब कुछ विशेष नहीं है, लेकिन मैं कहूंगा कि यह कुछ विशेष है, क्योंकि आमतौर पर लोग पुस्तकालयों के बारे में सोचते हैं क्योंकि वे स्पष्ट रूप से अपने कोड से कॉल करते हैं; मौलिक भाषा शब्दार्थ के कार्यान्वयन के बजाय। मुझे लगता है कि यहाँ ओपी की गलत धारणा यह है कि एक कंपाइलर केवल अधिक या कम सरल तरीके से कोड का अनुवाद करने के लिए है, बजाय इसके कि यह पुस्तकालय के साथ साधन के बजाय लेखक को निर्दिष्ट नहीं करता है।
मिलीमो।

7
@millimoose रनटाइम लाइब्रेरी स्पष्ट उपयोगकर्ता सहभागिता के बिना कई तरीकों से दृश्यों के पीछे काम करती है। अपवाद प्रचार और स्टैक अनइंडिंग / विध्वंसक कॉलिंग पर विचार करें। डायनामिक मेमोरी एलोकेशन पर विचार करें (जो आमतौर पर केवल एक फ़ंक्शन को कॉल नहीं कर रहा है, जैसा कि सी में है, यहां तक ​​कि जब कोई कचरा संग्रह नहीं है)। गतिशील प्रकार की जानकारी (कलाकारों आदि के लिए) को संभालने पर विचार करें। तो जीसी वास्तव में अद्वितीय नहीं है।
कोनराड रुडोल्फ

3
हाँ, मैं मानता हूँ कि मैंने अजीब तरह से कहा था। ऐसा सिर्फ इसलिए था क्योंकि मुझे कंपाइलर के वास्तविक होने पर संदेह था। लेकिन अब जब मैं इसके बारे में सोचता हूं, तो यह बहुत अधिक मायने रखता है। कंपाइलर केवल मानक पुस्तकालय के किसी अन्य भाग की तरह एक कचरा कलेक्टर को लिंक कर सकता है। मेरा मानना ​​है कि एक कचरे के संग्रहकर्ता की सोच से उपजी मेरी कुछ उलझनें दुभाषिए के कार्यान्वयन के एक हिस्से के रूप में हैं न कि अपने आप में एक अलग कार्यक्रम।
क्रिश्चियन डीन

23

हालांकि संकलित भाषाओं के साथ यह कैसे काम करेगा?

आपका कहना गलत है। एक प्रोग्रामिंग भाषा कुछ तकनीकी रिपोर्ट (अच्छे उदाहरण के लिए, R5RS देखें ) में लिखा एक विनिर्देश है । वास्तव में आप कुछ विशिष्ट भाषा कार्यान्वयन (जो एक सॉफ्टवेयर है) का उल्लेख कर रहे हैं ।

(कुछ प्रोग्रामिंग भाषाओं में खराब विनिर्देशन हैं, या यहां तक ​​कि लापता लोग हैं, या बस कुछ नमूना कार्यान्वयन के अनुरूप हैं; फिर भी, एक प्रोग्रामिंग भाषा एक व्यवहार को परिभाषित करती है - जैसे इसमें एक वाक्यविन्यास और शब्दार्थ है - यह एक सॉफ्टवेयर उत्पाद नहीं है, लेकिन हो सकता है कुछ सॉफ्टवेयर उत्पाद द्वारा कार्यान्वित ; कई प्रोग्रामिंग भाषाओं में कई कार्यान्वयन होते हैं; विशेष रूप से, "संकलित" कार्यान्वयन के लिए एक विशेषण है - भले ही कुछ प्रोग्रामिंग भाषाएं संकलक की तुलना में दुभाषियों द्वारा अधिक आसान तरीके से लागू की जाती हैं।)

मेरी समझ यह है कि एक बार संकलक ने स्रोत कोड को लक्ष्य कोड - विशेष रूप से देशी मशीन कोड - में संकलित किया है। इसका काम समाप्त हो गया है।

ध्यान दें कि दुभाषियों और संकलक का एक ढीला अर्थ है, और कुछ भाषा कार्यान्वयन दोनों के रूप में माना जा सकता है। दूसरे शब्दों में, बीच में एक निरंतरता है। नवीनतम ड्रैगन बुक पढ़ें और bytecode , JIT संकलन के बारे में सोचें , गतिशील रूप से C कोड जो कुछ "प्लगइन" में संकलित किया गया है, फिर उसी प्रक्रिया द्वारा dlopen (3) -ed (और वर्तमान मशीनों पर, यह तेजी से संगत होने के लिए पर्याप्त है) एक इंटरैक्टिव REPL , यह देखें )


मैं दृढ़ता से GC हैंडबुक पढ़ने की सलाह देता हूं । जवाब देने के लिए एक पूरी किताब चाहिए । इससे पहले, कचरा संग्रह विकिपीज पढ़ें (जो मुझे लगता है कि आपने नीचे पढ़ने से पहले पढ़ा है)।

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

तो कैसे संकलित कार्यक्रम कचरा एकत्र किया जा सकता है?

बस मशीन कोड का उत्सर्जन करके जो रनटाइम सिस्टम का उपयोग करता है (और "अनुकूल" और "संगत है")।

ध्यान दें कि आप विशेष रूप से बोहेम जीसी , रेवेनब्रुक के एमपीएस , या यहां तक ​​कि मेरे (अनमने) किश में कई कचरा संग्रह पुस्तकालय पा सकते हैं । और एक साधारण जीसी कोडिंग बहुत मुश्किल नहीं है (हालांकि, डिबगिंग यह कठिन है, और एक प्रतिस्पर्धी जीसी कोडिंग मुश्किल है )।

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

अन्य (अधिक कठिन) मामलों में, रनटाइम एक जनरेटिंग कॉपी कचरा संग्रह प्रदान करता है (एक विशिष्ट उदाहरण Ocaml कंपाइलर है, जो इस तरह के GC का उपयोग करके मशीन कोड को Ocaml कोड संकलित करता है)। तब समस्या कॉल बिंदु पर सभी बिंदुओं को ठीक से खोजने के लिए होती है , और उनमें से कुछ को जीसी द्वारा स्थानांतरित किया जाता है। तब कंपाइलर कॉल स्टैक फ्रेम का वर्णन करने वाले मेटा-डेटा उत्पन्न करता है, जो रनटाइम का उपयोग करता है। इसलिए कॉलिंग कन्वेंशन और ABI उस कार्यान्वयन (यानी संकलक) और रनटाइम सिस्टम के लिए विशिष्ट होते जा रहे हैं ।

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

संकलक कुछ कचरा संग्रह कार्यक्रम की एक प्रति संग्रहीत करता है और इसे प्रत्येक निष्पादन योग्य में पेस्ट करता है जो इसे उत्पन्न करता है?

की तरह। हालांकि, क्रम प्रणाली किसी साझा लाइब्रेरी, आदि कभी कभी (लिनक्स और कई अन्य POSIX सिस्टम पर) हो सकता है यह भी एक स्क्रिप्ट दुभाषिया, जैसे के लिए पारित किया जा सकता है (2) execve एक साथ मामला । या एक ईएलएफ दुभाषिया, योगिनी (5) और PT_INTERP, आदि देखें।

BTW, कचरा संग्रहण (और उनके रनटाइम सिस्टम) के साथ भाषा के लिए अधिकांश संकलक आज मुफ्त सॉफ्टवेयर हैं । इसलिए सोर्स कोड डाउनलोड करें और उसका अध्ययन करें।


5
आपका मतलब है कि एक स्पष्ट विनिर्देश के बिना कई प्रोग्रामिंग भाषा कार्यान्वयन हैं । हां, मैं इससे सहमत हूं। लेकिन मेरा कहना यह है कि एक प्रोग्रामिंग भाषा एक सॉफ्टवेयर नहीं है (जैसे कुछ संकलक या कुछ दुभाषिया)। यह कुछ ऐसा है जिसमें एक वाक्यविन्यास और एक शब्दार्थ है (शायद दोनों ही बीमार हैं)।
बेसिल स्टारीनेवविच

4
@KonradRudolph: यह पूरी तरह से "औपचारिक" और "विनिर्देश" की आपकी परिभाषा पर निर्भर करता है: -D इसमें ISO / IEC 30170: 2012 रूबी प्रोग्रामिंग लैंग्वेज स्पेसिफिकेशन है , जो रूबी 1.8 और 1.9 के चौराहे के एक छोटे उपसमुच्चय को निर्दिष्ट करता है। है रूबी युक्ति सुइट , सीमा मामलों है कि "निष्पादन कल्पना" का एक प्रकार के रूप में सेवा के उदाहरण का एक सेट। फिर, डेविड फ्लानगन और युकीहिरो मात्सुमोतो द्वारा द रूबी प्रोग्रामिंग लैंग्वेज
जॉर्ज डब्ल्यू मित्तग

4
इसके अलावा, रूबी प्रलेखनरूबी इश्यू ट्रैकर पर मुद्दों की चर्चा । रूबी-कोर (अंग्रेजी) और रूबी-देव (जापानी) मेलिंगलिस्ट पर चर्चा। समुदाय की सामान्य ज्ञान अपेक्षाएँ (जैसे Array#[]O (1) सबसे खराब स्थिति है, Hash#[]O (1) सबसे खराब स्थिति है)। और अंतिम लेकिन कम से कम नहीं: मैट का मस्तिष्क।
जॉर्ज डब्ल्यू मित्तग

6
@KonradRudolph: बिंदु यह है: यहां तक ​​कि कोई भी भाषा जिसमें कोई औपचारिक विनिर्देश नहीं है और केवल एक ही कार्यान्वयन अभी भी "भाषा" (अमूर्त नियम और प्रतिबंध) और "कार्यान्वयन" (उन नियमों और कोड प्रसंस्करण कोड के अनुसार) में विभाजित किया जा सकता है प्रतिबंध)। और कार्यान्वयन अभी भी एक विनिर्देशन को जन्म देता है, भले ही एक तुच्छ व्यक्ति है, अर्थात्: "कोड जो भी करता है वह कल्पना है"। यह कैसे आईएसओ कल्पना, RubySpec, और RDocs लिखा गया था, सब के बाद: witth और / या रिवर्स इंजीनियरिंग MRI के आसपास खेल कर।
जॉर्ज डब्ल्यू मित्तग

1
खुशी है कि आप बोहेम के कचरा कलेक्टर को ले आए। मैं ओपी को इसका अध्ययन करने की सलाह दूंगा क्योंकि यह एक साधारण उदाहरण है कि एक साधारण संकलक के लिए "बोल्ट पर" होने पर भी साधारण कचरा संग्रहण कैसे हो सकता है।
Cort Ammon

6

पहले से ही कुछ अच्छे उत्तर हैं, लेकिन मैं इस प्रश्न के पीछे कुछ गलतफहमियों को दूर करना चाहूंगा।

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

मूल रूप से और व्याख्या की गई कोड के बीच अंतर बहुत कम सख्त है जितना लगता है। दोनों को कुछ रनटाइम लाइब्रेरी और काम करने के लिए कुछ ऑपरेटिंग सिस्टम (*) की आवश्यकता होती है। व्याख्या किए गए कोड को एक दुभाषिया की आवश्यकता होती है, लेकिन दुभाषिया रनटाइम का एक हिस्सा है। लेकिन यह भी सख्त नहीं है, क्योंकि आप दुभाषिया को एक (सिर्फ-इन-टाइम) कंपाइलर से बदल सकते हैं। अधिकतम प्रदर्शन के लिए, आप दोनों (डेस्कटॉप जावा रनटाइम में एक दुभाषिया और दो संकलक शामिल हो सकते हैं) चाहते हैं।

कोई फर्क नहीं पड़ता कि कोड कैसे चलते हैं, इसे उसी तरह का व्यवहार करना चाहिए। स्मृति को आवंटित करना और मुक्त करना रनटाइम के लिए एक कार्य है (जैसे फाइलें खोलना, धागे शुरू करना आदि)। आपकी भाषा में आप सिर्फ लिखते हैं new X()या एक जैसे हैं। भाषा विनिर्देश कहता है कि क्या होना चाहिए और रनटाइम क्या करता है।

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

कोड की व्याख्या और कचरा संग्रह के बीच वास्तव में कोई सीधा संबंध नहीं है। यह सिर्फ इतना है कि C जैसी निम्न-स्तरीय भाषा हर चीज की गति और बारीक नियंत्रण के लिए डिज़ाइन की गई है, जो गैर-देशी कोड या कचरा कलेक्टर के विचार के साथ अच्छी तरह से फिट नहीं है। तो बस एक सहसंबंध है।

यह पुराने समय में बहुत सही था, जहां उदाहरण के लिए जावा दुभाषिया बहुत धीमा था और अयोग्य के बजाय कचरा इकट्ठा करने वाला। आजकल, चीजें बहुत अलग हैं और एक व्याख्या की गई भाषा के बारे में बोलने से कोई भी समझदारी खो गई है।


(*) सामान्य प्रयोजन कोड के बारे में बोलते समय, बूट लोडर और समान को छोड़कर।


Ocaml और SBCL दोनों देशी कंपाइलर हैं। तो वहाँ रहे हैं "मूल रूप से संकलित भाषा" कार्यान्वयन।
बेसिल स्टारीनेविच 11

@BasileStarynkevitch वाट? कुछ कम जाने-पहचाने कंपाइलरों का नामकरण मेरे जवाब से कैसे संबंधित है? मूल रूप से व्याख्या की गई भाषा के लिए SBCL एक संकलक के रूप में नहीं है जो मेरे दावे के पक्ष में एक तर्क है कि भेद का कोई मतलब नहीं है?
मातरिनस

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

@BasileStarynkevitch मैं यही दावा कर रहा हूं। 1. व्याख्या या संकलित भाषा के रूप में ऐसी कोई चीज नहीं है (हालांकि सी की शायद ही व्याख्या की जाती है और एलआईएसपी शायद ही कभी संकलित किया जाता था, लेकिन यह वास्तव में कोई फर्क नहीं पड़ता)। 2. अधिकांश प्रसिद्ध भाषाओं के लिए व्याख्या, संकलित और मिश्रित कार्यान्वयन हैं और संकलन या व्याख्या को छोड़कर कोई भाषा नहीं है।
माॅर्टिनस

6
मुझे लगता है कि आपका तर्क बहुत मायने रखता है। ग्रॉक करने का मुख्य बिंदु यह है कि आप हमेशा एक "देशी कार्यक्रम", या "कभी नहीं" चलाते हैं, हालांकि आप इसे देखना चाहते हैं। विंडोज पर कोई एक्स नहीं है, निष्पादन योग्य है; इसे शुरू करने के लिए एक लोडर और अन्य ओएस सुविधाओं की आवश्यकता है और वास्तव में आंशिक रूप से "व्याख्या" भी है। यह .net निष्पादनयोग्य के साथ अधिक स्पष्ट हो जाता है। java myprogके रूप में के रूप में अधिक या कम निवासी है grep myname /etc/passwdया ld.so myprogयह एक निष्पादन योग्य (जो इसका मतलब है कि) जो एक तर्क लेता है और डेटा के साथ संचालन करता है:।
पीटर ए। श्नाइडर

3

विवरण कार्यान्वयन के बीच भिन्न होते हैं, लेकिन इसके आम तौर पर निम्नलिखित में से कुछ संयोजन होते हैं:

  • एक रनटाइम लाइब्रेरी जिसमें एक जीसी शामिल है। यह मेमोरी एलोकेशन को हैंडल करेगा और "GC_now" फंक्शन सहित कुछ अन्य एंट्री पॉइंट्स होंगे।
  • कंपाइलर जीसी के लिए तालिकाओं का निर्माण करेगा ताकि यह पता चले कि कौन से फ़ील्ड किस प्रकार के डेटा संदर्भ हैं। यह प्रत्येक फ़ंक्शन के लिए स्टैक फ़्रेम के लिए भी किया जाएगा ताकि जीसी स्टैक से ट्रेस हो सके।
  • यदि जीसी वृद्धिशील है (जीसी गतिविधि कार्यक्रम के साथ इंटरल्यूड है) या समवर्ती (एक अलग थ्रेड में चलाता है) तो कंपाइलर जीसी डेटा संरचनाओं को अपडेट करने के लिए विशेष ऑब्जेक्ट कोड भी शामिल करेगा जब संदर्भ अपडेट किए जाते हैं। डेटा संगति के लिए दोनों में समान मुद्दे हैं।

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

जीसी एल्गोरिदम का 60 के दशक से अध्ययन किया गया है, और इस विषय पर व्यापक साहित्य है। यदि आप अधिक जानकारी चाहते हैं तो Google

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.