6

मैं कंपाइलर्स के बारे में एक कॉलेज कोर्स ले रहा हूं और हमने कचरा संग्रह और स्मृति मुक्त करने के तरीकों के बारे में बात करना समाप्त कर दिया है। हालांकि, कक्षा व्याख्यान और हमारी पाठ्यपुस्तक में, मुझे विश्वास था कि संदर्भ गिनती स्मृति का प्रबंधन करने का एक शानदार तरीका नहीं था।उद्देश्य-सी संदर्भ प्रभावी ढंग से गिनती कैसे करता है?

तर्क यह था कि संदर्भ गणना बहुत महंगा है क्योंकि कार्यक्रम को संदर्भ गणना बढ़ाने और घटाने के लिए कई अतिरिक्त निर्देश डालना पड़ता है। इसके अतिरिक्त, जब भी संदर्भ गणना बदलती है, प्रोग्राम को यह जांचना पड़ता है कि यह शून्य के बराबर है और यदि ऐसा है, तो स्मृति को पुनः प्राप्त करें।

मेरे पाठ्यपुस्तक भी वाक्य है:। "कुल मिलाकर, संदर्भ गिनती के साथ समस्याओं इसके फायदे outweight और यह शायद ही कभी प्रोग्रामिंग भाषा के वातावरण में स्वत: भंडारण प्रबंधन के लिए प्रयोग किया जाता है

मेरे प्रश्न हैं: इन वैध चिंताओं हैं क्या उद्देश्य-सी उन्हें किसी तरह से टालता है? यदि ऐसा है तो?

+2

"कई अतिरिक्त निर्देश" - numeruos == एक; 'आईएनसी [एएसपी +12]'। इसके अलावा, उद्देश्य-सी हाथ से ट्यूनेड असेंबली का उपयोग करता है और एक संकलित भाषा => तेज़ भी है। –

+2

उस आईएनसी पर एक एलओकेके उपसर्ग की आवश्यकता है, और यह ओबीजेसी की साइड टेबल को ध्यान में रखता है, और उपकरण –

+2

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

उत्तर

5

संदर्भ गिनती का अर्थपूर्ण ओवरहेड होता है, यह सच है। हालांकि, कचरा कलेक्टरों का पता लगाने का "क्लासिक पाठ्यपुस्तक" समाधान डाउनसाइड्स के बिना भी नहीं है। सबसे बड़ा nondeterminism, लेकिन विराम बनाम थ्रूपुट एक महत्वपूर्ण चिंता भी है।

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

(संपादित करें) मेरी व्यक्तिगत भावनाएं हैं कि थ्रूपुट एक माध्यमिक, या यहां तक ​​कि तृतीयक, चिंता है और वास्तव में महत्वपूर्ण बहस प्रतिलिपि बनाम चक्र संग्रह और प्रतिलिपि बनाकर ढेर संकलन के लिए नीचे आती है। उनमें से तीन ऐसे मूल्यवान गुण हैं जिन्हें मैं चुनने के लिए कड़ी मेहनत करूँगा।

+0

लेकिन महत्वपूर्ण, "सार्थक ओवरहेड" कीमत फ्लाई पर भुगतान की जाती है, क्योंकि विलोपन होता है (जैसा कि रेफ-गिनती में कमी की छोटी लागत के विपरीत) है, भले ही आपका कोड एक एकल रेफरी के परिणामस्वरूप पूरे ऑब्जेक्ट ग्राफ़ को हटा देता है -काउंट कमी, न केवल यह परिणाम है कि आपका कोड कैसे लिखा जाता है (आपका कोड उस गिनती को कम करने का फैसला करता है), लेकिन यह आपके ऐप के पूरे जीवनकाल में भी ऐसी लागत फैलता है, बिना किसी उपयोगकर्ता के ध्यान देने योग्य विराम के। ओएस एक्स पर ओबीजेसी के लिए कला जनरेशनल कचरा कलेक्टर की अपनी स्थिति भी समाप्त हो सकती है ... – verec

+1

libauto (ऐप्पल का जीसी) आंशिक रूप से रूढ़िवादी, गैर प्रतिलिपि बनाने वाला संग्राहक है जिसका मैंने उल्लेख किया है। इसमें झूठी जड़ों, ढेर विखंडन, और इतने प्रदर्शन के साथ समस्याएं हैं (हालांकि सामान्य सी कचरा कलेक्टरों की तुलना में काफी बेहतर है)। –

+0

आप निश्चित रूप से प्रतिलिपि बनाने और रोकथाम के बिना (जावा-स्टाइल) जीसी कर सकते हैं। –

0

कुल मिलाकर, संदर्भ गिनती के साथ समस्याओं इसके फायदे outweight और यह शायद ही कभी प्रोग्रामिंग भाषा के वातावरण

मुश्किल शब्द automatic

मैनुअल संदर्भ गिनती है में स्वत: भंडारण प्रबंधन के लिए प्रयोग किया जाता है जो चीजों को करने के लिए पारंपरिक ओब्जे-सी तरीका है, प्रोग्रामर को उन्हें सौंपकर समस्याओं से बचाता है। प्रोग्रामर को संदर्भ गणना के बारे में जानना है और मैन्युअल रूप से retain और release कॉल जोड़ें। यदि वह संदर्भ चक्र बनाता है, तो वह इसे हल करने के लिए ज़िम्मेदार है।

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

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

अतिरिक्त निर्देशों के कारण प्रदर्शन हानि बहुत बड़ी नहीं है और आमतौर पर यह महत्वपूर्ण नहीं है।

+0

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

1

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

यहाँ एक छोटे से बेंचमार्क मैं सिर्फ 3.1 गीगा i5 के साथ मेरी iMac पर किया था, आईओएस 7.1 64-बिट सिम्युलेटर में है:

long tenmillion = 10000000; 
NSTimeInterval t; 

t = [NSDate timeIntervalSinceReferenceDate]; 
NSMutableArray *arr = [NSMutableArray arrayWithCapacity:tenmillion]; 
for (long i = 0; i < tenmillion; ++i) 
    [arr addObject:[NSObject new]]; 
NSLog(@"%f seconds: Allocating ten million objects and putting them in an array.", [NSDate timeIntervalSinceReferenceDate] - t); 

t = [NSDate timeIntervalSinceReferenceDate]; 
for (NSObject *obj in arr) 
    [self doNothingWith:obj]; // Can't be optimized out because it's a method call. 
NSLog(@"%f seconds: Calling a method on an object ten million times.", [NSDate timeIntervalSinceReferenceDate] - t); 

t = [NSDate timeIntervalSinceReferenceDate]; 
NSObject *o; 
for (NSObject *obj in arr) 
    o = obj; 
NSLog(@"%f seconds: Setting a pointer ten million times.", [NSDate timeIntervalSinceReferenceDate] - t); 
एआरसी विकलांग के साथ

(-fno-objc-arc), यह निम्न देता है:

2.029345 seconds: Allocating ten million objects and putting them in an array. 
0.047976 seconds: Calling a method on an object ten million times. 
0.006162 seconds: Setting a pointer ten million times. 

एआरसी सक्षम होने के साथ, कि हो जाता है:

1.794860 seconds: Allocating ten million objects and putting them in an array. 
0.067440 seconds: Calling a method on an object ten million times. 
0.788266 seconds: Setting a pointer ten million times. 

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

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

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

संबंधित मुद्दे