कंपाइलर स्वचालित रूप से डीलोकेशन क्यों नहीं डालते हैं?


63

C जैसी भाषाओं में, प्रोग्रामर को मुफ्त में कॉल डालने की उम्मीद है। संकलक स्वचालित रूप से ऐसा क्यों नहीं करता है? मनुष्य इसे उचित समय में करते हैं (कीड़े की अनदेखी करते हैं), इसलिए यह असंभव नहीं है।

EDIT: भविष्य के संदर्भ के लिए, यहां एक और चर्चा है जिसका एक दिलचस्प उदाहरण है।


125
और यह कि, बच्चों, इसीलिए हम आपको कम्प्यूटेबिलिटी सिद्धांत सिखाते हैं। ;)
राफेल

7
यह एक संगणनीय समस्या नहीं है क्योंकि मानव सभी मामलों में निर्णय नहीं ले सकता है। यह एक संपूर्णता समस्या है; डील्लोकेशन स्टेटमेंट में ऐसी जानकारी होती है, जिसे यदि हटा दिया जाता है, तो विश्लेषण द्वारा पूरी तरह से पुनर्प्राप्त नहीं किया जा सकता है जब तक कि उस विश्लेषण में परिनियोजन वातावरण और अपेक्षित ऑपरेशन के बारे में जानकारी शामिल न हो, जिसमें C स्रोत कोड शामिल नहीं है।
नेट

41
नहीं, यह एक संगणना समस्या है। यह निर्विवाद है कि क्या स्मृति के एक टुकड़े को निपटाया जाना चाहिए। एक निश्चित कार्यक्रम के लिए, कोई उपयोगकर्ता इनपुट या अन्य बाहरी हस्तक्षेप नहीं करता है।
बाउर

1
टिप्पणियाँ विस्तारित चर्चा के लिए नहीं हैं; इस वार्तालाप को बातचीत में स्थानांतरित कर दिया गया है । सभी टिप्पणियां जो विशेष रूप से प्रश्न को संबोधित नहीं करती हैं और इसे कैसे सुधार किया जा सकता है, इसे दृष्टि पर हटा दिया जाएगा।
राफेल

2
@BorisTreukhov, कृपया इसे चैटरूम में ले जाएं। नहीं, मुझे नहीं लगता कि लेडी कह रही है कि बचना विश्लेषण "असंभव" है (हालांकि इस संदर्भ में वास्तव में इसका क्या अर्थ है यह निर्धारित करना मेरे लिए थोड़ा अस्पष्ट है)। पूरी तरह से सटीक भागने विश्लेषण है अनिर्णनीय। सभी के लिए: कृपया इसे चैटरूम में ले जाएं । कृपया केवल यहाँ टिप्पणी पोस्ट करें जो प्रश्न को बेहतर बनाने के उद्देश्य से हैं - अन्य चर्चा और कमेंटरी को चैट रूम में पोस्ट किया जाना चाहिए।
DW

जवाबों:


80

क्योंकि यह अपरिहार्य है कि क्या प्रोग्राम फिर से मेमोरी का उपयोग करेगा। इसका मतलब यह है कि free()सभी मामलों में कॉल करने के दौरान कोई भी एल्गोरिथ्म सही ढंग से निर्धारित नहीं कर सकता है , जिसका अर्थ है कि ऐसा करने वाला कोई भी कंपाइलर आवश्यक रूप से मेमोरी लीक और / या कुछ प्रोग्राम का उत्पादन करेगा जो कि मेमोरी का उपयोग करना जारी रखता था जिसे मुक्त कर दिया गया था। यहां तक ​​कि अगर आपने यह सुनिश्चित किया है कि आपके कंपाइलर ने कभी दूसरा नहीं किया और प्रोग्रामर को free()उन बग्स को ठीक करने के लिए कॉल डालने की अनुमति दी , तो free()उस कंपाइलर को कॉल करने के लिए जानते हुए भी free()कंपाइलर का उपयोग करते समय कॉल करने के समय जानने की तुलना में कठिन हो जाएगा। मदद करने।


12
हमारे पास एक सवाल है जो अयोग्य समस्याओं को हल करने के लिए मनुष्यों की क्षमता को कवर करता है । मैं आपको एक ऐसे कार्यक्रम का उदाहरण नहीं दे सकता जो गलत तरीके से संकलित किया जाएगा क्योंकि यह इस बात पर निर्भर करता है कि कंपाइलर किस एल्गोरिदम का उपयोग करता है। लेकिन कोई भी एल्गोरिथ्म असीम रूप से कई अलग-अलग कार्यक्रमों के लिए गलत आउटपुट का उत्पादन करेगा।
डेविड रिचेर्बी

1
टिप्पणियाँ विस्तारित चर्चा के लिए नहीं हैं; इस वार्तालाप को बातचीत में स्थानांतरित कर दिया गया है ।
गाइल्स

2
दोस्तों, यह चैट करने के लिए ले लो । सब कुछ जो सीधे उत्तर से संबंधित नहीं है और इसे कैसे सुधार किया जा सकता है, इसे हटा दिया जाएगा।
राफेल

2
बहुत सारी चीज़ें जो कंपाइलर ख़ुशी से करते हैं, सामान्य रूप से अनिर्दिष्ट हैं; अगर हम हमेशा राइस के प्रमेय की ओर इशारा करते हैं तो हमें कंपाइलर दुनिया में कहीं भी नहीं मिलेगा।
तिखन जेल्विस

3
यह अप्रासंगिक है। यदि यह सभी संकलक के लिए अनिर्दिष्ट है, तो यह सभी मनुष्यों के लिए भी असाध्य है। फिर भी हम मनुष्यों से free()सही ढंग से सम्मिलित होने की अपेक्षा करते हैं ।
पॉल ड्रेपर

53

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

यहां तक ​​कि सटीक गतिशील कचरा संग्रह एक अकल्पनीय समस्या है! सभी वास्तविक दुनिया के कचरा संग्राहक भविष्य में एक आवंटित वस्तु की आवश्यकता होगी या नहीं, इसके लिए एक रूढ़िवादी सन्निकटन के रूप में पुनर्जन्म का उपयोग करते हैं। यह एक अच्छा सन्निकटन है, लेकिन फिर भी यह एक सन्निकटन है।

लेकिन यह केवल सामान्य रूप से सच है। कंप्यूटर विज्ञान व्यवसाय में सबसे कुख्यात कॉप-आउट में से एक है "यह सामान्य रूप से असंभव है, इसलिए हम कुछ भी नहीं कर सकते हैं"। इसके विपरीत, ऐसे कई मामले हैं जहां कुछ प्रमुख बनाना संभव है।

संदर्भ गणना के आधार पर कार्यान्वयन "संकलक डालने वाले सौदे" के बहुत करीब हैं, जैसे कि अंतर बताना मुश्किल है। LLVM की स्वचालित संदर्भ गणना ( ऑब्जेक्टिव-सी और स्विफ्ट में प्रयुक्त ) एक प्रसिद्ध उदाहरण है।

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

अब, मनुष्यों के विषय पर, तीन मुख्य तरीके हैं जो मनुष्य आबंटित आजीविका को मैन्युअल रूप से प्रबंधित करते हैं:

  1. कार्यक्रम और समस्या को समझने से। उदाहरण के लिए मनुष्य समान आबंटन वस्तु में समान जीवनकाल वाली वस्तुओं को रख सकता है। कंपाइलर और कचरा इकट्ठा करने वालों को इसका पता लगाना चाहिए, लेकिन इंसानों को अधिक सटीक जानकारी होती है।
  2. केवल जरूरत पड़ने पर गैर-पुस्तक बुक-कीपिंग (जैसे रेफरेंस काउंटिंग) या अन्य विशेष आवंटन तकनीकों (जैसे जोनों) का उपयोग करके। फिर से, एक मानव यह जान सकता है कि एक कंपाइलर को इसका पता कैसे लगाना चाहिए।
  3. बुरी तरह। हर कोई वास्तविक दुनिया में तैनात कार्यक्रमों के बारे में जानता है जिनके पास धीमी लीक है, आखिरकार। या अगर वे नहीं करते हैं, तो कभी-कभी कार्यक्रमों और आंतरिक एपीआई को स्मृति जीवनकाल, पुन: प्रयोज्यता और प्रतिरूपकता को कम करने के लिए पुनर्गठन करने की आवश्यकता होती है।

टिप्पणियाँ विस्तारित चर्चा के लिए नहीं हैं। यदि आप घोषणात्मक बनाम कार्यात्मक पर चर्चा करना चाहते हैं, तो कृपया इसे चैट में करें
गिल्स

2
यह प्रश्न का सबसे अच्छा उत्तर है (जो बहुत से उत्तरों को भी संबोधित नहीं करता है)। आप Conseervative GC पर हंस बोहेम के अग्रणी कार्य का संदर्भ जोड़ सकते थे : en.wikipedia.org/wiki/Boehm_garbage_collector । एक और दिलचस्प बात यह है कि डेटा लाइनिंग (या एक विस्तारित अर्थ में उपयोगिता) को एक सार शब्दार्थ या एक निष्पादन मॉडल के संबंध में परिभाषित किया जा सकता है। लेकिन विषय वास्तव में व्यापक है।
बबौ

29

यह एक अपूर्णता समस्या है, न कि एक अनिर्णायक समस्या

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

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

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

लेकिन अगर सी सोर्स कोड डीलक्लोकेशन के लिए कोई स्पष्ट कमांड नहीं देता है, तो कंपाइलर को यह पता लगाने की आवश्यकता होगी कि उपयोगकर्ता द्वारा आरईपीएल में उचित कमांड इनपुट करने पर यह डेलोकेशन करना चाहिए। क्या वह कमांड "डीललॉकेट", "फ्री", या कुछ और है? कंपाइलर को यह जानने का कोई तरीका नहीं है कि आप क्या कमांड चाहते हैं। यहां तक ​​कि अगर आप उस कमांड शब्द को देखने के लिए तर्क में प्रोग्राम करते हैं और आरईपीएल इसे ढूंढता है, तो कंपाइलर को यह जानने का कोई तरीका नहीं है कि इसे तब तक जवाब देना चाहिए जब तक कि आप स्पष्ट रूप से इसे सोर्स कोड में न बताएं।

tl; dr समस्या है C स्रोत कोड बाहरी ज्ञान के साथ संकलक प्रदान नहीं करता है। अनिश्चयता मुद्दा नहीं है क्योंकि यह वहां है कि क्या प्रक्रिया मैनुअल या स्वचालित है।


3
टिप्पणियाँ विस्तारित चर्चा के लिए नहीं हैं; इस वार्तालाप को बातचीत में स्थानांतरित कर दिया गया है । आगे की सभी टिप्पणियां जो विशेष रूप से इस उत्तर की कमियों को संबोधित नहीं करती हैं और उन्हें कैसे ठीक किया जा सकता है, इसे दृष्टि पर हटा दिया जाएगा।
राफेल

23

वर्तमान में, पोस्ट किए गए उत्तरों में से कोई भी पूरी तरह से सही नहीं है।

कंपाइलर स्वचालित रूप से डीलोकेशन क्यों नहीं डालते हैं?

  1. कुछ करते हैं। (मैं बाद में समझाता हूँ।)

  2. त्रैमासिक, आप free()कार्यक्रम से बाहर निकलने से ठीक पहले कॉल कर सकते हैं । लेकिन free()जितनी जल्दी हो सके कॉल करने के लिए आपके प्रश्न में एक निहित आवश्यकता है।

  3. free()किसी भी सी प्रोग्राम में कॉल करने की समस्या, जैसे ही मेमोरी अगम्य है, अनिर्णायक है, यानी किसी भी एल्गोरिथ्म के लिए परिमित समय में उत्तर प्रदान करने के लिए, एक ऐसा मामला है जो इसे कवर नहीं करता है। यह - और कई अन्य अनियंत्रित कार्यक्रमों की मनमानी - हॉल्टिंग समस्या से साबित हो सकती है ।

  4. एक अपरिहार्य समस्या हमेशा किसी भी एल्गोरिथ्म द्वारा सीमित समय में हल नहीं की जा सकती है, चाहे वह एक संकलक हो या एक मानव।

  5. मनुष्य सी कार्यक्रमों के एक सबसेट में लिखते हैं (जिसे उनके एल्गोरिथ्म (स्वयं) द्वारा स्मृति शुद्धता के लिए सत्यापित किया जा सकता है।

  6. कुछ भाषाएँ संकलक में # 5 का निर्माण करके # 1 को पूरा करती हैं। वे स्मृति आवंटन के मनमाने ढंग से उपयोग के साथ कार्यक्रम की अनुमति नहीं देते हैं, बल्कि उनमें से एक निर्णायक उपसमूह है। फोथ और रस्ट उन भाषाओं के दो उदाहरण हैं जिनमें सी की तुलना में अधिक प्रतिबंधात्मक मेमोरी आवंटन है malloc(), जो (1) यह पता लगा सकता है कि क्या प्रोग्राम उनके डिसीडेबल सेट (2) के बाहर स्वचालित रूप से सम्मिलित करता है।


1
मुझे समझ में आ गया कि जंग कैसे होती है। लेकिन मैंने ऐसा करने वाले फोर्थ के बारे में कभी नहीं सुना। क्या आप विस्तार से समझा सकते हैं?
मिल्टन सिल्वा

2
@MiltonSilva, फोर्थ - कम से कम इसकी सबसे बुनियादी, मूल कार्यान्वयन - केवल एक ढेर है, ढेर नहीं। यह कॉल स्टैक पॉइंटर को स्थानांतरित करने के लिए आवंटन / डीक्लोकेशन करता है, एक कार्य जिसे कंपाइलर आसानी से कर सकता है। फोर्थ को बहुत ही सरल हार्डवेयर को लक्षित करने के लिए बनाया गया था, और कभी-कभी गैर-गतिशील मेमोरी सभी के लिए व्यावहारिक होती है। यह स्पष्ट रूप से गैर-तुच्छ कार्यक्रमों के लिए एक व्यावहारिक समाधान नहीं है।
पॉल ड्रेपर

10

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

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


1
मानवीय पतन के आधार को स्वीकार करने और फिर भी मानव निर्मित सोच मशीनों को अभी भी अचूक हो सकता है (अर्थात मनुष्य से बेहतर) की धारणा कम प्रसिद्ध है लेकिन अधिक पेचीदा है। एकमात्र धारणा जिसमें से क्रिया आगे बढ़ सकती है वह यह है कि मानव मन में पूरी तरह से गणना करने की क्षमता है।
वाइल्डकार्ड

1. मैंने कभी नहीं कहा कि सोच की मशीनें अचूक हो सकती हैं। मनुष्यों की तुलना में बेहतर वे पहले से ही कई मामलों में हैं। 2. कार्रवाई के लिए एक शर्त के रूप में पूर्णता (यहां तक ​​कि संभावित) की उम्मीद एक बेतुका है।
एंड्रे सूजा लेमोस

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

आशय, मशीनों में मनुष्यों के रूप में, हमेशा बाहर से आता है ।
एंड्रे सूजा लेमोस

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

9

स्वचालित स्मृति प्रबंधन की कमी भाषा की एक विशेषता है।

सी आसानी से सॉफ्टवेयर लिखने के लिए एक उपकरण नहीं माना जाता है। यह कंप्यूटर को बनाने का एक उपकरण है जो आप इसे करने के लिए कहते हैं। जिसमें आपके चयन के क्षण में मेमोरी आवंटित करना और डील करना शामिल है। C एक निम्न-स्तरीय भाषा है जिसका उपयोग आप तब करते हैं जब आप कंप्यूटर को ठीक से नियंत्रित करना चाहते हैं, या जब आप भाषा / मानक पुस्तकालय डिजाइनरों से अपेक्षा के अनुरूप चीजों को अलग तरीके से करना चाहते हैं।


टिप्पणियाँ विस्तारित चर्चा के लिए नहीं हैं; इस वार्तालाप को बातचीत में स्थानांतरित कर दिया गया है ।
डीडब्ल्यू

2
यह (CS भाग) प्रश्न का उत्तर कैसे है?
राफेल

6
@ राफेल कंप्यूटर विज्ञान का मतलब यह नहीं है कि हमें अस्पष्ट तकनीकी उत्तरों की तलाश करनी चाहिए। कंपाइलर कई चीजें करते हैं जो सामान्य मामले में असंभव हैं। यदि हम स्वचालित स्मृति प्रबंधन चाहते हैं, तो हम इसे कई तरीकों से लागू कर सकते हैं। C ऐसा नहीं करता है, क्योंकि यह करने वाला नहीं है।
जौनी साइरन

9

मुद्दा ज्यादातर ऐतिहासिक कलाकृतियों का है, कार्यान्वयन की असंभवता का नहीं।

जिस तरह से अधिकांश सी कंपाइलर कोड का निर्माण करते हैं, ताकि कंपाइलर प्रत्येक स्रोत फ़ाइल को एक बार में देख सके; यह कभी भी पूरे कार्यक्रम को एक साथ नहीं देखता है। जब एक स्रोत फ़ाइल किसी अन्य स्रोत फ़ाइल या लाइब्रेरी से फ़ंक्शन को कॉल करती है, तो सभी कंपाइलर फ़ंक्शन के रिटर्न प्रकार के साथ हेडर फ़ाइल को देखता है, फ़ंक्शन का वास्तविक कोड नहीं। इसका मतलब है कि जब कोई फ़ंक्शन होता है जो एक पॉइंटर लौटाता है, तो कंपाइलर के पास यह बताने का कोई तरीका नहीं है कि मेमोरी पॉइंटर को फ्रीज करने की आवश्यकता है या नहीं। उस समय पर संकलक को नहीं दिखाया जाता है यह तय करने की जानकारी। एक मानव प्रोग्रामर, दूसरी तरफ, फ़ंक्शन के स्रोत कोड को देखने के लिए स्वतंत्र है या यह पता लगाने के लिए दस्तावेज है कि पॉइंटर के साथ क्या करने की आवश्यकता है।

यदि आप C ++ 11 या Rust जैसी अधिक आधुनिक निम्न-स्तरीय भाषाओं में देखते हैं, तो आप पाएंगे कि वे ज्यादातर सूचक के प्रकार में मेमोरी स्वामित्व को स्पष्ट करके समस्या का समाधान करते हैं। C ++ में आप मेमोरी को होल्ड करने के लिए unique_ptr<T>प्लेन के बजाय का उपयोग करेंगे T*और यह unique_ptr<T>सुनिश्चित करेंगे कि ऑब्जेक्ट को स्कोप के विपरीत स्कोप के अंत तक पहुँचने पर मेमोरी फ़्री हो जाए T*। प्रोग्रामर मेमोरी को एक unique_ptr<T>से दूसरे को सौंप सकता है , लेकिन मेमोरी में केवल एक ही unique_ptr<T>पॉइंटिंग हो सकती है । इसलिए यह हमेशा स्पष्ट होता है कि स्मृति का मालिक कौन है और इसे कब मुक्त किया जाना है।

C ++, पश्चगामी अनुकूलता कारणों के लिए, फिर भी पुरानी शैली के मैनुअल मेमोरी प्रबंधन की अनुमति देता है और इस तरह से बग या तरीके के निर्माण की सुरक्षा को दरकिनार कर देता है unique_ptr<T>। जंग और भी सख्त है कि यह संकलक त्रुटियों के माध्यम से स्मृति स्वामित्व नियमों को लागू करता है।

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


टिप्पणियाँ विस्तारित चर्चा के लिए नहीं हैं; इस वार्तालाप को बातचीत में स्थानांतरित कर दिया गया है ।
राफेल

6

अन्य उत्तरों पर ध्यान केंद्रित किया गया है कि क्या कचरा संग्रह करना संभव है, कुछ विवरण यह कैसे किया जाता है, और कुछ समस्याएं।

एक मुद्दा जो अभी तक कवर नहीं किया गया है, हालांकि कचरा संग्रहण में अपरिहार्य देरी है। सी में, जब कोई प्रोग्रामर मुफ्त कॉल करता है (), तो वह मेमोरी तुरंत पुन: उपयोग के लिए उपलब्ध है। (सिद्धांत में कम से कम!) इसलिए एक प्रोग्रामर अपनी 100MB संरचना को मुक्त कर सकता है, बाद में एक और 100MB संरचना को एक मिलीसेकेंड आवंटित कर सकता है, और समग्र मेमोरी उपयोग समान रहने की उम्मीद करता है।

यह कचरा संग्रह के साथ सच नहीं है। कचरा एकत्र करने वाली प्रणालियों में ढेर के लिए अप्रयुक्त मेमोरी को वापस करने में कुछ देरी होती है, और यह महत्वपूर्ण हो सकता है। यदि आपकी 100MB संरचना दायरे से बाहर हो जाती है, और एक मिलीसेकंड बाद में आपका कार्यक्रम एक और 100MB संरचना सेट करता है, तो आप अपने सिस्टम से 200 एमबी का उपयोग करने की उम्मीद कर सकते हैं। यह "छोटी अवधि" प्रणाली के आधार पर मिलीसेकंड या सेकंड हो सकती है, लेकिन अभी भी देरी है।

यदि आप RAM और वर्चुअल मेमोरी के साथ पीसी पर चल रहे हैं, तो निश्चित रूप से आप इस पर कभी गौर नहीं करेंगे। यदि आप अधिक सीमित संसाधनों (हालांकि, एक एम्बेडेड सिस्टम या एक फोन) के साथ एक सिस्टम पर चल रहे हैं, तो यह ऐसी चीज है जिसे आपको गंभीरता से लेने की आवश्यकता है। यह सिर्फ सैद्धांतिक नहीं है - मैंने व्यक्तिगत रूप से इसे समस्याएं पैदा करते देखा है (जैसे डिवाइस की समस्याओं को दुर्घटनाग्रस्त करने में) जब .NET कॉम्पैक्ट फ्रेमवर्क का उपयोग करके WinCE सिस्टम पर काम करना और C # में विकसित करना।


आप हर आवंटन से पहले जीसी सिद्धांत में चला सकते हैं।
एड्रियन एन १३'१

4
@adrianN लेकिन व्यवहार में ऐसा नहीं किया गया क्योंकि यह मानसिक होगा। ग्राहम की बात अभी भी कायम है: जीसीएस हमेशा पर्याप्त ओवरहेड को उकसाता है, या तो रनटाइम के संदर्भ में या आवश्यक अधिशेष स्मृति के संदर्भ में। आप इस बैलेंस को या तो चरम की ओर मोड़ सकते हैं लेकिन आप मूल रूप से ओवरहेड को हटा नहीं सकते हैं।
कोनराड रुडोल्फ

"देरी" जब स्मृति मुक्त हो जाती है तो वर्चुअल-मेमोरी सिस्टम में सीमित संसाधनों वाले सिस्टम की तुलना में अधिक समस्या होती है। पूर्व के मामले में, एक कार्यक्रम के लिए यह बेहतर हो सकता है कि 200MB का उपयोग करने के लिए 200MB की तुलना में, भले ही सिस्टम में 200MB उपलब्ध हो , लेकिन बाद वाले मामले में पहले की तुलना में GC चलाने का कोई लाभ नहीं होगा जब तक कि विलंब कुछ के दौरान अधिक स्वीकार्य नहीं होगा दूसरों की तुलना में कोड के कुछ हिस्सों।
सुपरकैट

मैं यह देखने में विफल रहता हूं कि यह (CS भाग) प्रश्न का उत्तर देने का प्रयास कैसे किया जाता है।
राफेल

1
@ राफेल मैंने कचरे के संग्रह के सिद्धांत के साथ एक अच्छी तरह से पहचानी गई समस्या बताई है, जो कि सीएस को इसके मूल नुकसानों में से एक के रूप में सिखाया जाता है (या होना चाहिए)। मैंने इसे व्यवहार में देखने का अपना व्यक्तिगत अनुभव भी दिया है, यह दिखाने के लिए कि यह शुद्ध रूप से सैद्धांतिक समस्या नहीं है। यदि आप इस बारे में कुछ समझने में असफल रहे, तो मुझे इस विषय पर अपने ज्ञान को सुधारने के लिए बात करने में खुशी हो रही है।
ग्राहम

4

सवाल यह माना जाता है कि एक डीलरशिप कुछ ऐसा है जिसे प्रोग्रामर को स्रोत कोड के अन्य भागों से कटौती करना चाहिए। यह। "कार्यक्रम के इस बिंदु पर, मेमोरी संदर्भ FOO अब उपयोगी नहीं है" प्रोग्रामर के दिमाग में केवल तब तक ज्ञात जानकारी होती है जब तक कि उसे (प्रक्रियात्मक भाषाओं में) एक डीक्लोकेशन स्टेटमेंट में एनकोड नहीं किया जाता है।

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

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


4
"कार्यक्रम में इस बिंदु पर, स्मृति संदर्भ FOO अब उपयोगी नहीं है 'केवल प्रोग्रामर के दिमाग में ज्ञात जानकारी है" - यह स्पष्ट रूप से गलत है। क) कई FOO के लिए, यह पता लगाने के लिए तुच्छ है, जैसे कि मूल्य शब्दार्थ के साथ स्थानीय चर। बी) आप सुझाव देते हैं कि प्रोग्रामर यह जानता है, हमेशा, जो स्पष्ट रूप से एक अत्यधिक आशावादी धारणा है; यदि यह सच था, तो हमारे पास खराब मेमोरी हैंडलिंग के कारण कोई गंभीर बग नहीं है जो सुरक्षा-महत्वपूर्ण सॉफ़्टवेयर है। जो, अफसोस, हम करते हैं।
राफेल

मैं सिर्फ सुझाव दे रहा हूं कि भाषा उन मामलों के लिए डिज़ाइन की गई थी जहां प्रोग्रामर को पता है कि FOO अब उपयोगी नहीं है। मैं सहमत हूं, स्पष्ट रूप से, यह आमतौर पर सच नहीं है, और इसलिए हमें स्थैतिक विश्लेषण और / या कचरा संग्रह करने की आवश्यकता है। जो, हुर्रे, हम करते हैं। लेकिन ओपी का सवाल यह है कि वे चीजें हाथ से कोड किए गए सौदागरों के समान मूल्यवान नहीं हैं ?
ट्रैविस विल्सन

4

क्या किया जाता है: कचरा संग्रह है, और संदर्भ गिनती (उद्देश्य-सी, स्विफ्ट) का उपयोग करके संकलक हैं। जो संदर्भ गणना करते हैं, उन्हें मजबूत संदर्भ चक्र से बचकर प्रोग्रामर की मदद की आवश्यकता होती है।

असली का जवाब "क्यों" है कि संकलक लेखकों एक तरीका है कि काफी अच्छा और काफी तेजी से यह एक संकलक में प्रयोग करने योग्य बनाने के लिए है पता चल नहीं किया है। चूंकि कंपाइलर लेखक आमतौर पर काफी स्मार्ट होते हैं इसलिए आप यह निष्कर्ष निकाल सकते हैं कि यह बहुत ही कठिन है, एक ऐसा तरीका ढूंढना है जो काफी अच्छा हो और काफी तेज हो।

कारणों में से एक यह है कि यह बहुत कठिन है, निश्चित रूप से यह अयोग्य है। कंप्यूटर विज्ञान में, जब हम "निर्णायक" के बारे में बात करते हैं तो हमारा मतलब है "सही निर्णय लेना"। मानव प्रोग्रामर निश्चित रूप से आसानी से तय कर सकते हैं कि मेमोरी को कहां से डील करना है, क्योंकि वे सही फैसलों तक सीमित नहीं हैं । और वे अक्सर ऐसे निर्णय लेते हैं जो गलत हैं।


मैं यहां योगदान देखने में विफल हूं।
बबौ

3

C जैसी भाषाओं में, प्रोग्रामर को मुफ्त में कॉल डालने की उम्मीद है। संकलक स्वचालित रूप से ऐसा क्यों नहीं करता है?

क्योंकि एक मेमोरी ब्लॉक का जीवनकाल प्रोग्रामर का निर्णय होता है, न कि कंपाइलर का।

बस। यह सी का डिज़ाइन है। संकलक यह नहीं जान सकता कि मेमोरी ब्लॉक आवंटित करने का इरादा क्या था। मनुष्य इसे कर सकते हैं, क्योंकि वे हर मेमोरी ब्लॉक के उद्देश्य को जानते हैं और जब इस उद्देश्य को पूरा किया जाता है तो इसे मुक्त किया जा सकता है। यह उस कार्यक्रम के डिजाइन का हिस्सा है जिसे लिखा जा रहा है।

C निम्न-स्तरीय भाषा है, इसलिए आपकी मेमोरी के ब्लॉक को किसी अन्य प्रक्रिया या किसी अन्य प्रोसेसर पर भी भेजने की घटनाएं काफी होती हैं। चरम मामले में, एक प्रोग्रामर जानबूझकर मेमोरी का एक हिस्सा आवंटित कर सकता है और सिस्टम के अन्य हिस्सों पर मेमोरी दबाव डालने के लिए इसे फिर से उपयोग नहीं करता है। कंपाइलर को यह जानने का कोई तरीका नहीं है कि क्या ब्लॉक अभी भी आवश्यक है।


-1

C जैसी भाषाओं में, प्रोग्रामर को मुफ्त में कॉल डालने की उम्मीद है। संकलक स्वचालित रूप से ऐसा क्यों नहीं करता है?

सी और कई अन्य भाषाओं में, कंपाइलर को उन मामलों में इसके बराबर करने के लिए वास्तव में एक सुविधा है जिसमें यह संकलन समय पर स्पष्ट है जब इसे किया जाना चाहिए: स्वचालित-अवधि चर (सामान्य स्थानीय चर) का उपयोग । कंपाइलर ऐसे चर के लिए पर्याप्त जगह की व्यवस्था करने के लिए जिम्मेदार है, और उस स्थान को जारी करने के लिए जब उनका (अच्छी तरह से परिभाषित) जीवनकाल समाप्त होता है।

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

जिन वस्तुओं का इच्छित उपयोग उन्हें स्वत: अवधि प्रदान करने की अनुमति देता है, वे ठीक वही हैं जिनका जीवनकाल संकलन समय पर निर्धारित नहीं किया जा सकता है।

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