दिलचस्प पोस्ट
एक बटन क्लिक किए जाने पर jQuery का उपयोग करते हुए एक ऑडियो फ़ाइल चलाएं मैं फ़ायरफ़ॉक्स ऐडॉन कैसे लिखूं? मुख्य कार्य की वापसी मूल्य सीमा SO_REUSEADDR का उपयोग करता है? $ http.get (…) .Success एक फ़ंक्शन नहीं है "रूटर-आउटलेट" बाल घटकों (एन्सेलर 2) में डेटा पास करना विकल्प के साथ अनंत लूप सीटीई (अधिकतम क्रैकशन 0) परीक्षण stream.good () या! Stream.eof () पिछली पंक्ति को दो बार पढ़ता है मैं UILabel डिस्प्ले को रेखांकित टेक्स्ट कैसे बनाऊं? वर्ण वैक्टर के आर वर्गीकरण के नियम क्या हैं? एसक्यूएललेमी: वास्तविक क्वेरी प्रिंट करें ES6 मॉड्यूल आयात करने के लिए विकल्प पास करें एक कक्षा के सभी उदाहरणों को छपाई स्प्रिंग डाटा रेस्ट और कॉर्स मान त्रुटि: नकारात्मक संख्या को एक आंशिक शक्ति के लिए नहीं बढ़ाया जा सकता है

सी ++ में कचरा कलेक्टर क्यों नहीं है?

मैं यह सवाल नहीं पूछ रहा हूं क्योंकि कचरा संग्रह के गुणों को सबसे पहले। यह पूछने के लिए मेरा मुख्य कारण यह है कि मुझे पता है कि बर्जने स्ट्राउटस्ट्रुप ने कहा है कि सी + + समय में कुछ समय पर कचरा कलेक्टर होगा।

इसके साथ कहा, क्यों नहीं जोड़ा गया है? सी ++ के लिए पहले से ही कुछ कचरा कलेक्टर हैं क्या यह सिर्फ उन चीजों में से एक है, जो "चीजों की तुलना में आसान" कहा जाता है? या क्या इसमें कोई अन्य कारण नहीं जोड़ा गया है (और सी ++ 11 में नहीं जोड़ा जाएगा)?

क्रॉस लिंक:

  • कचरा कलेक्टरों के लिए सी ++

बस स्पष्ट करने के लिए, मैं समझता हूं कि सी + + के पास कचरा कलेक्टर नहीं था जब यह पहली बार बनाया गया था। मैं सोच रहा हूं कि कलेक्टर को क्यों नहीं जोड़ा जा सकता

Solutions Collecting From Web of "सी ++ में कचरा कलेक्टर क्यों नहीं है?"

अंतर्निहित कचरा संग्रह में जोड़ा जा सकता था, लेकिन यह कटौती नहीं कर सका। संभवतः सिर्फ कार्यान्वयन जटिलताओं के कारण नहीं, बल्कि लोगों की वजह से एक सामान्य सहमति में तेजी से पर्याप्त रूप से आने में सक्षम नहीं है।

बर्जनी स्ट्राउटस्ट्रुप से एक उद्धरण:

मुझे उम्मीद थी कि कचरा कलेक्टर जिसे वैकल्पिक रूप से सक्षम किया जा सकता है, वह सी ++ 0x का हिस्सा होगा, लेकिन पर्याप्त तकनीकी समस्याएं थीं, मुझे सिर्फ एक विस्तृत विवरण के साथ करना पड़ता है कि कैसे इस तरह के कलेक्टर शेष भाषा के साथ एकीकृत करता है , यदि उपलब्ध कराया गया है वैसे ही सभी सी ++ 0 एक्स सुविधाओं के मामले में, एक प्रयोगात्मक कार्यान्वयन मौजूद है।

यहां विषय की एक अच्छी चर्चा है

सामान्य अवलोकन:

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

सी ++ प्रतियोगियों के साथ बनाया गया था जो कि कचरा संग्रह नहीं था। दक्षता मुख्य चिंता थी कि सी ++ को सी और अन्य की तुलना में आलोचना को दूर करना पड़ा।

कचरा संग्रह के 2 प्रकार हैं …

स्पष्ट कचरा संग्रहण:

सी ++ 0 एक्स में कूटबन्धन संकलन साझा आईपीटीआर के साथ बनाया गया है

यदि आप चाहते हैं कि आप इसका उपयोग कर सकते हैं, अगर आप यह नहीं चाहते हैं तो आप इसका उपयोग करने के लिए मजबूर नहीं हैं।

यदि आप सी ++ 0x के लिए इंतजार नहीं करना चाहते हैं, तो आप वर्तमान में बढ़ावा: shared_ptr का उपयोग कर सकते हैं।

सम्मिलित कूड़ा संग्रह:

इसमें पारदर्शी कचरा संग्रह नहीं है हालांकि। भविष्य में सी ++ ऐप के लिए यह फोकस बिंदु होगा।

क्यों Tr1 में गंदा कचरा संग्रह नहीं है?

कई चीजें हैं जो सी 1 + 0x का tr1 होनी चाहिए थी, पिछले साक्षात्कार में बर्न स्ट्रावट्रुप ने कहा था कि tr1 के पास जितना पसंद होता उतना नहीं था।

यहां बहस को जोड़ने के लिए

कचरा संग्रहण के साथ ज्ञात मुद्दे हैं, और समझने में मदद करता है कि सी ++ में कोई भी क्यों नहीं है

1. प्रदर्शन?

पहली शिकायत अक्सर प्रदर्शन के बारे में है, लेकिन ज्यादातर लोगों को वास्तव में पता नहीं है कि वे किस बारे में बात कर रहे हैं। जैसे कि Martin Beckett द्वारा दिखाया गया समस्या समस्या का प्रति प्रदर्शन नहीं हो सकती है, लेकिन प्रदर्शन की अनुमानिता

वर्तमान में जीसी के 2 परिवार हैं जो व्यापक रूप से तैनात किए गए हैं:

  • मार्क-एंड-स्वीप की तरह
  • संदर्भ-गणना की तरह

Mark And Sweep तेजी से (समग्र प्रदर्शन पर कम प्रभाव) है, लेकिन यह "फ्रीज द वर्ल्ड" सिंड्रोम से ग्रस्त है: यानी जब जीसी में किक होता है, तो बाकी सब कुछ बंद हो जाता है जब तक जीसी ने इसकी सफाई नहीं की है। यदि आप एक सर्वर का निर्माण करना चाहते हैं जो कुछ मिलीसेकंड में उत्तर देता है … कुछ लेन-देन आपकी अपेक्षाओं तक नहीं रहेंगे 🙂

Reference Counting की समस्या अलग है: संदर्भ-गिनती ओवरहेड जोड़ती है, खासकर मल्टी थ्रेडिंग वातावरण में क्योंकि आपको परमाणु गिनती की आवश्यकता है इसके अलावा संदर्भ चक्र की समस्या है ताकि आपको उन चक्रीय एल्गोरिदम की आवश्यकता हो और उन चक्रों को समाप्त कर दें (आम तौर पर "फ़्रीज द वर्ल्ड" भी लागू होता है, हालांकि कम अक्सर)। सामान्य तौर पर, आज की तरह, इस तरह की (हालांकि सामान्य रूप से अधिक प्रतिक्रियाशील या बजाए, कम बार फ्रीजिंग) Mark And Sweep की तुलना में धीमी है

मेरे पास एफिल कार्यान्वयनकर्ताओं द्वारा एक पेपर देखा गया है जो Reference Counting कूड़ा कलेक्टर को लागू करने की कोशिश कर रहे थे, जो "फ्रीज द वर्ल्ड" पहलू के बिना Mark And Sweep समान वैश्विक प्रदर्शन होगा। जीसी (ठेठ) के लिए इसे अलग थ्रेड की आवश्यकता है। एल्गोरिदम थोड़ा भयावह (अंत में) था, लेकिन कागज ने एक समय में अवधारणाओं को शुरू करने और "सरल" संस्करण से पूर्णांकित करने के लिए एल्गोरिदम के विकास का एक अच्छा काम किया। यदि केवल पीडीएफ फाइल पर अपना हाथ वापस रख सकता है तो सिफारिश की पढ़ाई …

2. संसाधन अधिग्रहण प्रारंभ है

यह C++ में एक सामान्य मुहावरे C++ कि आप किसी ऑब्जेक्ट के भीतर संसाधनों के स्वामित्व को यह सुनिश्चित करने के लिए लपेट लेंगे कि वे ठीक से रिलीज़ किए गए हैं चूंकि हमारे पास कूड़ा संग्रह नहीं है, इसलिए यह ज्यादातर स्मृति के लिए प्रयोग किया जाता है, लेकिन कई अन्य स्थितियों के लिए यह भी उपयोगी है:

  • तालों (बहु धागा, फ़ाइल संभाल, …)
  • कनेक्शन (एक डेटाबेस, एक और सर्वर, …)

विचार ऑब्जेक्ट के जीवनकाल को ठीक से नियंत्रित करना है:

  • यह तब तक ज़िंदा होना चाहिए जितना आपको इसकी ज़रूरत है
  • जब आप इसे पूरा कर लेंगे तो इसे मार दिया जाना चाहिए

जीसी की समस्या यह है कि यदि यह पूर्व के साथ मदद करता है और आखिरकार गारंटी देता है कि … यह "अंतिम" पर्याप्त नहीं हो सकता है यदि आप लॉक जारी करते हैं, तो आप वास्तव में इसे पसंद करेंगे कि अब इसे जारी किया जाए, ताकि यह किसी और कॉल को रोक नहीं सकें!

जीसी के साथ भाषाएँ दो काम के आसपास हैं:

  • जब स्टैक आवंटन पर्याप्त होता है तो जीसी का उपयोग न करें: यह सामान्यतः प्रदर्शन के मुद्दों के लिए होता है, लेकिन हमारे मामले में यह वास्तव में मदद करता है क्योंकि दायरे जीवनकाल को परिभाषित करता है
  • निर्माण using … लेकिन यह स्पष्ट (कमजोर) आरएआई है जबकि सी + + आरएआईआई में निहित है ताकि उपयोगकर्ता अनजाने में त्रुटि (खोजशब्द को छोड़कर) कर सकता है

3. स्मार्ट पॉइंटर्स

स्मार्ट पॉइंटर्स अक्सर C++ में मेमोरी को संभालने के लिए रजत बुलेट के रूप में दिखाई देते हैं कई बार मैंने सुना है: हमारे पास जीसी की आवश्यकता नहीं है, क्योंकि हमारे पास स्मार्ट पॉइंटर्स हैं

एक और अधिक गलत नहीं हो सकता

स्मार्ट पॉइंटर्स मदद करते हैं: auto_ptr और unique_ptr RAII अवधारणाओं का उपयोग करते हैं, वास्तव में बहुत उपयोगी unique_ptr हैं unique_ptr वे इतने सरल हैं कि आप उन्हें अपने आप से काफी आसानी से लिख सकते हैं

जब किसी को स्वामित्व साझा करने की आवश्यकता होती है, लेकिन इसे और अधिक कठिन हो जाता है: आप कई धागे के बीच साझा कर सकते हैं और गिनती को संभालने में कुछ सूक्ष्म मुद्दे हैं इसलिए, एक स्वाभाविक रूप से shared_ptr की ओर जाता है

यह महान है, यह सब के लिए बूस्ट क्या है, लेकिन यह एक चांदी की गोली नहीं है। वास्तव में, shared_ptr साथ मुख्य मुद्दा यह है कि यह Reference Counting द्वारा लागू एक जीसी को emulates करता है लेकिन आपको अपने द्वारा चक्र पहचान को कार्यान्वित करने की आवश्यकता है … Urg

बेशक यह weak_ptr बात है, लेकिन दुर्भाग्य से पहले ही उन चक्रों के कारण shared_ptr weak_ptr के उपयोग के बावजूद मेमोरी लीक देखा गया है … और जब आप एक मल्टी थ्रेड पर्यावरण में हैं, तो इसका पता लगाना बहुत मुश्किल है!

4. समाधान क्या है?

कोई चांदी की गोली नहीं है, लेकिन हमेशा की तरह, यह निश्चित रूप से संभव है। जीसी की अनुपस्थिति में एक को स्वामित्व पर स्पष्ट होना चाहिए:

  • यदि किसी भी समय एक ही मालिक होने पर संभव हो, तो संभव है
  • यदि नहीं, तो सुनिश्चित करें कि आपके क्लास आरेख में स्वामित्व से संबंधित कोई चक्र नहीं है और उन्हें weak_ptr सूक्ष्म अनुप्रयोग से weak_ptr

तो वास्तव में, जीसी होना बहुत अच्छा होगा … लेकिन यह कोई तुच्छ मुद्दा नहीं है। और मतलब समय में, हमें बस हमारी आस्तीन को रोल करने की जरूरत है।

किस प्रकार का? क्या इसे एम्बेडेड वॉशिंग मशीन नियंत्रकों, सेलफोन, वर्कस्टेशन या सुपरकंपर्स के लिए अनुकूलित किया जाना चाहिए?
क्या यह GUI जवाबदेही या सर्वर लोडिंग को प्राथमिकता देनी चाहिए?
क्या इसे बहुत सी मेमोरी या बहुत से सीपीयू का उपयोग करना चाहिए?

सी / सी ++ का प्रयोग सिर्फ कई अलग-अलग परिस्थितियों में किया जाता है मुझे संदेह है कि बढ़ावा देने वाला स्मार्ट पॉइंटर्स अधिकांश उपयोगकर्ताओं के लिए पर्याप्त होगा

संपादित करें – स्वचालित कचरा लेनेवाले प्रदर्शन की बहुत ज्यादा समस्या नहीं है (आप हमेशा अधिक सर्वर खरीद सकते हैं) यह पूर्वानुमानित प्रदर्शन का प्रश्न है।
नहीं जानते कि जीसी जब किक करने जा रहा है, तो नार्कोप्टीक एयरलाइन पायलट को रोजगार देने जैसा है, ज्यादातर समय वे महान हैं – लेकिन जब आपको वास्तव में जवाबदेही की आवश्यकता होती है!

सबसे बड़ा कारण है कि सी ++ कचरा संग्रहण में निर्मित नहीं है, यह है कि कचरा संग्रहण नाश करने वालों के साथ अच्छा खेलना वास्तव में बहुत मुश्किल है। जहां तक ​​मुझे पता है, कोई भी वास्तव में इसे पूरी तरह से अभी तक हल करने का नहीं जानता है। इससे निपटने के लिए कई मुद्दे हैं:

  • वस्तुओं के नियतात्मक जीवन काल (संदर्भ गणना आपको यह देता है, लेकिन जीसी नहीं है। हालांकि यह एक बड़ा सौदा नहीं हो सकता है)।
  • क्या होता है अगर एक कचरा इकट्ठा किया जा रहा है जब एक नाशक फेंकता है? अधिकांश भाषाओं इस अपवाद को अनदेखा करते हैं, क्योंकि वास्तव में कोई कैच ब्लॉक नहीं है, इसे परिवहन के लिए सक्षम होने के लिए, लेकिन यह शायद सी ++ के लिए एक स्वीकार्य समाधान नहीं है।
  • इसे कैसे सक्षम / अक्षम करें? स्वाभाविक रूप से यह संभवतः एक संकलन समय निर्णय होगा, लेकिन जीसी बनाम कोड के लिए लिखा गया कोड, जो कि जीसी के लिए लिखा नहीं है, बहुत अलग और शायद असंगत होने वाला है। आप इसे कैसे सुलझ सकते हैं?

इन समस्याओं का सिर्फ कुछ ही सामना करना पड़ता है

यद्यपि यह एक पुराना सवाल है, फिर भी एक समस्या यह है कि मुझे किसी को भी संबोधित नहीं किया गया है: कचरा संग्रहण निर्दिष्ट करना लगभग असंभव है

विशेष रूप से, सी ++ मानक काफी सावधान है कि बाह्य व्यवहार के संदर्भ में भाषा को निर्दिष्ट करने के बजाय, कार्यान्वयन उस व्यवहार को कैसे प्राप्त करता है। कचरा संग्रह के मामले में, हालांकि, वास्तव में बाह्य रूप से कोई अवलोकनत्मक व्यवहार नहीं है।

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

यदि आप ऑब्जेक्ट्स नहीं ले सकते हैं, तो आप एक एकल, आसन्न मेमोरी स्पेस नहीं बना सकते, जिससे आपके आवंटन करना है – और इसका मतलब है कि आपका ढेर (या फ्री स्टोर या जो भी आप इसे कॉल करना पसंद करते हैं), और शायद समय के साथ विखंडित हो गया बदले में यह, सफल होने से आवंटन को रोका जा सकता है, भले ही अनुरोध किया जा रहा राशि की तुलना में अधिक स्मृति मुक्त हो।

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

फिर भी, यह C ++ के लिए प्रस्तावित की गई तुलना में अधिक मजबूत है पिछले प्रस्ताव [चेतावनी: पीडीएफ] (जो गिरा हुआ है) ने कुछ भी गारंटी नहीं दी थी। प्रस्ताव के 28 पन्नों में, बाहरी रूप से दिखाए जाने योग्य व्यवहार के रास्ते में जो भी मिला है वह एक एकल (गैर-प्रामाणिक) नोट कह रहा था:

[नोट: कचरा एकत्रित कार्यक्रमों के लिए, एक उच्च गुणवत्ता वाली होस्ट की गई कार्यान्वयन को प्राप्त करने योग्य मेमोरी की मात्रा को अधिकतम करने का प्रयास करना चाहिए जो इसे पुनः प्राप्त करता है। -नोट नोट]

कम से कम मेरे लिए, यह निवेश पर रिटर्न के बारे में एक गंभीर सवाल उठाता है हम मौजूदा कोड को तोड़ने जा रहे हैं (कोई भी निश्चित नहीं है कि वास्तव में कितना, लेकिन निश्चित तौर पर काफी कुछ), कार्यान्वयन पर नई आवश्यकताएं और कोड पर नए प्रतिबंध, और बदले में जो कुछ भी मिलता है, वह काफी संभवतः बिल्कुल नहीं है?

यहां तक ​​कि सबसे अच्छे रूप में, हम जो प्रोग्राम प्राप्त करते हैं, वे प्रोग्राम होते हैं, जो जावा के साथ परीक्षण के आधार पर संभवतः लगभग छह गुना ज्यादा मेमोरी की आवश्यकता होती है, जो वे अब उसी गति से चलते हैं। इससे भी बदतर, कचरा संग्रहण शुरुआत से जावा का हिस्सा था – सी ++ कचरा कलेक्टर पर अधिक प्रतिबंध लगाता है कि यह लगभग निश्चित रूप से एक भी बदतर लागत / लाभ अनुपात होगा (भले ही हम प्रस्ताव की गारंटी से परे जाएं और मान लें कि वहां होगा कुछ लाभ)

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

यदि आप स्वचालित कचरा संग्रहण चाहते हैं, तो सी ++ के लिए अच्छा वाणिज्यिक और सार्वजनिक-डोमेन कचरा कलेक्टर हैं ऐसे अनुप्रयोगों के लिए जहां कचरा संग्रह उपयुक्त है, सी ++ एक उत्कृष्ट कचरा एकत्रित भाषा है जो अन्य कचरा एकत्रित भाषाओं के साथ तुलनात्मक रूप से तुलना करता है। C ++ में स्वचालित कचरा संग्रह की चर्चा के लिए सी ++ प्रोग्रामिंग भाषा (तीसरा संस्करण) देखें यह भी देखें, हंस-जे सी और सी + + कचरा संग्रह के लिए Boehm की साइट। साथ ही, सी ++ प्रोग्रामिंग तकनीकों का समर्थन करता है जो कचरा कलेक्टर के बिना मेमोरी प्रबंधन को सुरक्षित और निहित होने की अनुमति देता है।

स्रोत: http://www.stroustrup.com/bs_faq.html#garbage-collection

अगर यह सही है कि मुझे जीसी से पहले ही इसका आविष्कार हुआ है, तो यह क्यों नहीं बनाया गया है , और मुझे विश्वास नहीं है कि इस भाषा में कई कारणों से जीसी हो सकती थी (IE पिछड़े सी के साथ पीछे की तरफदारी)

उम्मीद है की यह मदद करेगा।

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

कुछ भी प्रकार के स्मार्ट पॉइंटर्स का उपयोग करने से आपको कुछ नहीं रोकता है जो कुछ तृतीय-पक्ष कचरा संग्रहण तंत्र के लिए बाध्य हैं। मुझे माइक्रोसॉफ्ट को कॉम के साथ ऐसा कुछ याद करना लगता है और यह अच्छी तरह से नहीं चला था।

स्ट्राउटस्ट्रुप ने 2013 की जा रहे मूल निवासी सम्मेलन में इस पर कुछ अच्छी टिप्पणियां कीं।

बस इस वीडियो में लगभग 25m50 के लिए छोड़ दें (मैं वास्तव में पूरे वीडियो को देखने की सलाह देता हूं, लेकिन यह कचरा संग्रहण के बारे में सामानों को छोड़ देता है।)

जब आपके पास वास्तव में एक महान भाषा होती है जो वस्तुओं और मूल्यों को प्रत्यक्ष तरीके से निपटने के लिए (स्पष्ट) उपयोग से बचने के लिए आसान (और सुरक्षित, और पूर्वानुमानित और आसान-से-पढ़ी और आसान-सिखाने) बनाता है ढेर, तो आप भी कचरा संग्रह नहीं करना चाहती

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

वह इस उदाहरण को दिखाता है:

 void f(int n, int x) { Gadget *p = new Gadget{n}; if(x<100) throw SomeException{}; if(x<200) return; delete p; } 

यह सी ++ में असुरक्षित है लेकिन जावा में भी असुरक्षित है! सी ++ में, अगर समारोह जल्दी लौटाता है, तो delete लिए कभी भी कॉल नहीं किया जाएगा। लेकिन अगर आपके पास जावा में पूर्ण कूड़ा संग्रह है, तो आप केवल एक सुझाव प्राप्त कर सकते हैं कि वस्तु "भविष्य में कुछ बिंदु पर" नष्ट हो जाएगी ( अपडेट: यह इससे भी बदतर है।) जावा कभी अंतिम निर्माता को कॉल करने का वादा नहीं करता – इसे कभी भी नहीं कहा जा सकता है)। यह अच्छा नहीं है यदि गैजेट एक खुली फ़ाइल संभाल, या डेटाबेस के लिए कनेक्शन, या डेटा जिसे आप बाद में एक डेटाबेस में लिखने के लिए buffered हैं हम चाहते हैं कि जितनी जल्दी हो सके गैजेट को नष्ट कर दिया जाए, जितनी जल्दी हो सके इन संसाधनों को मुक्त करने के लिए। आप नहीं चाहते कि आपका डाटाबेस सर्वर हजारों डेटाबेस कनेक्शनों से जूझ रहा है जो अब जरूरी नहीं है – यह नहीं पता है कि आपका प्रोग्राम काम कर रहा है

तो समाधान क्या है? कुछ दृष्टिकोण हैं स्पष्ट दृष्टिकोण है, जिसका उपयोग आप अपनी अधिकांश वस्तुओं के लिए करेंगे:

 void f(int n, int x) { Gadget p = {n}; // Just leave it on the stack (where it belongs!) if(x<100) throw SomeException{}; if(x<200) return; } 

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

आपके द्वारा किए जाने वाले अधिकांश ऑब्जेक्ट फंक्शन में केवल उन्हें बनाए गए हैं, और संभवत: बाल फ़ंक्शन के लिए इनपुट के रूप में उत्तीर्ण किए गए हैं। प्रोग्रामर को ऑब्जेक्ट्स लौटते समय 'मेमोरी प्रबंधन' के बारे में सोचना नहीं चाहिए, या सॉफ़्टवेयर के व्यापक रूप से अलग हिस्सों में ऑब्जेक्ट को साझा करना चाहिए।

क्षेत्र और जीवनकाल महत्वपूर्ण हैं अधिकांश समय, यह आसान है यदि जीवनकाल दायरे के समान है। यह समझना आसान है और सिखाना आसान है जब आप एक अलग जीवनकाल चाहते हैं, उदाहरण के लिए shared_ptr उपयोग के द्वारा कोड को पढ़ना स्पष्ट होना चाहिए, यह आप कर रहे हैं। (या लौटकर (बड़े) ऑब्जेक्ट्स ऑब्जेक्ट, unique_ptr ले-सिमेंटिक या unique_ptr

यह एक दक्षता समस्या की तरह लग सकता है अगर मैं foo() से गैजेट वापस करना चाहता हूं तो क्या होगा? C ++ 11 की चाल शब्दों में बड़ी ऑब्जेक्ट्स को वापस करना आसान होता है। बस Gadget foo() { ... } लिखिए और यह केवल काम करेगा, और जल्दी से काम करे आप को अपने साथ गड़बड़ करने की ज़रूरत नहीं है, केवल मूल्य के आधार पर चीजें लौटाएं और भाषा अक्सर आवश्यक अनुकूलन करने में सक्षम हो जाएगी। (सी ++ 03 से पहले, कंपलर अनावश्यक प्रतिलिपि से बचने में काफी अच्छा काम करता था।)

Stroustrup के रूप में वीडियो (paraphrasing) में कहीं और कहा: "केवल एक कंप्यूटर वैज्ञानिक एक वस्तु की प्रतिलिपि बनाने पर जोर देगी, और फिर मूल को नष्ट कर देगा (दर्शक हंसते हैं)। सिर्फ ऑब्जेक्ट को सीधे नए स्थान पर क्यों नहीं ले जाते हैं? यह मनुष्य है (कंप्यूटर वैज्ञानिक नहीं) उम्मीद करते हैं। "

जब आप किसी ऑब्जेक्ट की केवल एक कॉपी की गारंटी दे सकते हैं, तो ऑब्जेक्ट के जीवनकाल को समझना बहुत आसान है। यदि आप चाहते हैं कि आप क्या जीवन भर की नीति चुन सकते हैं, और कचरा संग्रहण वहाँ है लेकिन जब आप अन्य तरीकों के लाभों को समझते हैं, तो आप पाएंगे कि कचरा संग्रहण वरीयताओं की सूची के नीचे है।

यदि वह आपके लिए काम नहीं करता है, तो आप unique_ptr उपयोग कर सकते हैं, या इसे विफल कर सकते हैं, shared_ptr अच्छी तरह से लिखा सी ++ 11 स्मृति प्रबंधन की बात आती है, जब कि कई अन्य भाषाओं की तुलना में कम, आसान-से-पढ़ने के लिए और आसान-सिखाना है।

C ++ के बारे में अधिकतर "क्यों" प्रश्नों का उत्तर देने के लिए, सी ++ के डिजाइन और विकास पढ़ें

सभी तकनीकी बातें अवधारणा को पूरा करना है

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

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

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

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

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

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

और पाठ्यक्रम का दूसरा महत्वपूर्ण कारण ग्लोबल वैरिएबल है। कलेक्टर के लिए यह जानने के लिए कि वैश्विक चर सूचक जीसी में है, इसके लिए विशिष्ट खोजशब्दों की आवश्यकता होगी, और इस तरह मौजूदा सी ++ कोड काम नहीं करेगा।

संक्षिप्त उत्तर: हम नहीं जानते कि कचरा संग्रह कुशलतापूर्वक कैसे करें (मामूली समय और स्थान ओवरहेड के साथ) और सही तरीके से हर समय (सभी संभव मामलों में)।

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

यह प्रश्न को विराम देता है: कचरा संग्रह प्रदर्शन को क्यों रोकता है? इसका मुख्य कारण यह है कि, जब यह कार्यान्वयन की बात आती है, तो हम [कंप्यूटर वैज्ञानिकों] को नहीं पता कि सभी मामलों के लिए कचरा संग्रह को न्यूनतम ओवरहेड के साथ कैसे करना है। Hence it's impossible to the C++ compiler and runtime system to perform garbage collection efficiently all the time. On the other hand, a C++ programmer, should know his design/implementation and he's the best person to decide how to best do the garbage collection.

Last, if control (hardware, details, etc.) and performance (time, space, power, etc.) are not the main constraints, then C++ is not the write tool. Other language might serve better and offer more [hidden] runtime management, with the necessary overhead.

When you compare C++ with Java, you can see immediately that C++ was not designed with implicit Garbage Collection in mind, while Java was.

Having things like arbitrary pointers in C-Style and deterministic destructors does not only slow down the performance of GC-implementations, it would also destroy backward compatibility for a large amount of C++-legacy-code.

In addition to that, C++ is a language that is intended to run as standalone executable instead of having a complex run-time environment.

All in all: Yes it would be possible to add Garbage Collection to C++, but for the sake of continuity it is better not to do so. The cost of doing so would be greater than the benefit.

One of the fundamental principles behind the original C language is that memory is composed of a sequence of bytes, and code need only care about what those bytes mean at the exact moment that they are being used. Modern C allows compilers to impose additional restrictions, but C includes–and C++ retains–the ability to decompose a pointer into a sequence of bytes, assemble any sequence of bytes containing the same values into a pointer, and then use that pointer to access the earlier object.

While that ability can be useful–or even indispensable–in some kinds of applications, a language that includes that ability will be very limited in its ability to support any kind of useful and reliable garbage collection. If a compiler doesn't know everything that has been done with the bits that made up a pointer, it will have no way of knowing whether information sufficient to reconstruct the pointer might exist somewhere in the universe. Since it would be possible for that information to be stored in ways that the computer wouldn't be able to access even if it knew about them (eg the bytes making up the pointer might have been shown on the screen long enough for someone to write them down on a piece of paper), it may be literally impossible for a computer to know whether a pointer could possibly be used in the future.

An interesting quirk of many garbage-collected frameworks is that an object reference not defined by the bit patterns contained therein, but by the relationship between the bits held in the object reference and other information held elsewhere. In C and C++, if the bit pattern stored in a pointer identifies an object, that bit pattern will identify that object until the object is explicitly destroyed. In a typical GC system, an object may be represented by a bit pattern 0x1234ABCD at one moment in time, but the next GC cycle might replace all references to 0x1234ABCD with references to 0x4321BABE, whereupon the object would be represented by the latter pattern. Even if one were to display the bit pattern associated with an object reference and then later read it back from the keyboard, there would be no expectation that the same bit pattern would be usable to identify the same object (or any object).

Mainly for two reasons:

  1. Because it doesn't need one (IMHO)
  2. Because it's pretty much incompatible with RAII, which is the cornerstone of C++

C++ already offers manual memory management, stack allocation, RAII, containers, automatic pointers, smart pointers… That should be enough. Garbage collectors are for lazy programmers who don't want to spend 5 minutes thinking about who should own which objects or when should resources be freed. That's not how we do things in C++.