2010-04-26 16 views
12

ठीक है यह सौदा है। कुछ ऐसे लोग हैं जिन्होंने अपने जीवन को .NET के कचरा कलेक्टर के हाथों में रखा है और कुछ जो इसे विश्वास नहीं करते हैं।.NET कचरा कलेक्टर की क्षमता

मैं जो आंशिक रूप से यह भरोसा करता है में से एक हूं, जब तक यह बहुत प्रदर्शन महत्वपूर्ण नहीं है के रूप में (मैं जानता हूँ कि मैं जानता हूँ कि .. प्रदर्शन महत्वपूर्ण + नेट नहीं इष्ट संयोजन), जिस स्थिति में मैं मैन्युअल के निपटान के लिए पसंद करते हैं मेरे वस्तुओं और संसाधनों।

मैं क्या पूछ रहा हूं कि क्या कोई तथ्य है कि कचरा कलेक्टर वास्तव में कितना कुशल या अक्षम प्रदर्शन है?

कृपया कोई व्यक्तिगत राय या संभावित धारणा-आधारित अनुभव साझा न करें, मुझे निष्पक्ष तथ्य चाहिए। मैं भी कोई प्रो/कॉन चर्चा नहीं चाहता क्योंकि यह सवाल का जवाब नहीं देगा।

धन्यवाद

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

मैं वास्तविकता पर एक उत्तर प्राप्त करने का प्रयास कर रहा हूं कि जीसी क्या करता है और यह कहां विफल हो सकता है और जहां यह विफल हो सकता है जहां मैन्युअल मेमोरी प्रबंधन सफल होगा यदि ऐसे परिदृश्य हैं। क्या इसमें सीमाएं हैं? मुझे नहीं पता कि मैं अपने प्रश्न को आगे कैसे समझा सकता हूं।

मुझे किसी भी अनुप्रयोग के साथ कोई समस्या नहीं है, यह सैद्धांतिक प्रश्न है।

+6

कुशल परिभाषित करें। यह जानने के बिना कि आप अपनी दक्षता को मापना चाहते हैं, इसका जवाब देना मुश्किल है। –

+0

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

+0

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

उत्तर

9

अधिकांश अनुप्रयोगों के लिए पर्याप्त कुशल है। लेकिन आपको जीसी के डर में जीना नहीं है। वास्तव में गर्म प्रणालियों पर, कम विलंबता आवश्यकताओं, आपको एक ऐसे फैशन में प्रोग्राम करना चाहिए जो पूरी तरह से इससे बचा जाए। मेरा सुझाव है कि आप इस Rapid Addition White Paper को देखो:

हालांकि जीसी काफी तेजी से किया जाता है, यह आपके निरंतर ऑपरेटिंग मोड में प्रदर्शन करने के लिए, और इस तरह कचरा संग्रहण दोनों अवांछनीय विलंबता और में भिन्नता लागू कर सकते हैं समय लेने के लिए करता है उन अनुप्रयोगों में विलंबता जो देरी से संवेदनशील हैं। एक चित्रण के रूप में, आप प्रति सेकंड 100,000 संदेशों कार्रवाई कर रहे हैं और प्रत्येक संदेश एक छोटे से अस्थायी 2 चरित्र स्ट्रिंग का उपयोग करता है, 8 बाइट (इस स्ट्रिंग एन्कोडिंग के एक समारोह और स्ट्रिंग वस्तु की कार्यान्वयन) के आसपास अगर आवंटित किया जाता है प्रत्येक संदेश के लिए। इस प्रकार आप प्रति सेकंड लगभग 1 एमबी कचरा बना रहे हैं। एक सिस्टम के लिए जो को 16 घंटे की अवधि में निरंतर प्रदर्शन वितरित करने की आवश्यकता है, इसका मतलब है कि आपको 16 घंटे x 60 मिनट x 60 सेकेंड x 1 एमबी मेमोरी लगभग 56 जीबी मेमोरी साफ़ करना होगा। सबसे अच्छा आप कचरा कलेक्टर से उम्मीद कर सकते हैं यह है कि यह यह पूरी तरह साफ हो जाएगा या तो पीढ़ी 0 या 1 संग्रह और कारण घबराना में, सबसे खराब है कि यह जुड़े के साथ एक जनरेशन 2 कचरा संग्रह का कारण होगा है बड़ा विलंबता स्पाइक।

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

+0

धन्यवाद उस जानकारी के लिए एक टन, वास्तव में इसकी सराहना करते हैं। –

+0

यह कुछ दिलचस्प पढ़ना था और मेरे कई सवालों का जवाब दिया, धन्यवाद। –

1

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

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

+0

उत्तर के लिए धन्यवाद, यह वास्तव में कोई चिंता नहीं है, मुझे लगता है कि यह कुछ ऐसा है जो आपको कुछ ज्ञान होना चाहिए, इसलिए मैं यही नहीं पूछ रहा हूं। –

2

आपको इसके बारे में चिंता करने की आवश्यकता नहीं है।

कारण यह है कि यदि आपको कभी भी एक बढ़िया मामला मिल जाता है जहां जीसी काफी समय ले रहा है, तो आप स्पॉट ऑप्टिमाइज़ेशन करके इसका सामना कर पाएंगे। यह दुनिया का अंत नहीं होगा - यह शायद बहुत आसान होगा।

और आपको ऐसे किनारे के मामलों को खोजने की संभावना नहीं है। यह वास्तव में आश्चर्यजनक रूप से अच्छा प्रदर्शन करता है। यदि आपने केवल सामान्य सी और सी ++ कार्यान्वयन में हीप आवंटकों का अनुभव किया है, तो .NET जीसी एक पूरी तरह से अलग जानवर है। मैं I wrote this blog post to try and get the point across से बहुत आश्चर्यचकित था।

2

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

कुछ जीसी हैं जो वास्तविक समय की गारंटी प्रदान करते हैं। "रीयल-टाइम" का अर्थ "तेज़" नहीं है, इसका मतलब है कि आवंटक प्रतिक्रिया समय को बाध्य किया जा सकता है। यह गारंटी की तरह है जो एम्बेडेड सिस्टम के लिए जरूरी है जैसे कि विमान में विद्युत आदेश चलाते हैं। आश्चर्यजनक रूप से पर्याप्त, मैन्युअल आवंटकों के मुकाबले कचरा कलेक्टरों के साथ वास्तविक समय की गारंटी रखना आसान है।

वर्तमान .NET कार्यान्वयन में जीसी रीयल-टाइम नहीं है; वे स्वाभाविक रूप से कुशल और तेज़ हैं। ध्यान दें कि सी (या new सी ++ में malloc()) के साथ मैन्युअल आवंटन के बारे में भी कहा जा सकता है, ताकि यदि आप रीयल-टाइम गारंटी के बाद हैं तो आपको पहले से ही कुछ विशेष उपयोग करने की आवश्यकता है। यदि आप नहीं करते हैं, तो मैं नहीं चाहता कि आप उन कारों और विमानों के लिए एम्बेडेड इलेक्ट्रॉनिक्स डिज़ाइन करें जिन्हें मैं उपयोग करता हूं!

5

मैं आपको .NET के कचरा कलेक्टर के साथ हुई कुछ समस्याओं के बारे में बता सकता हूं।

आप सर्वर जीसी (जैसे एक ASP.NET अनुप्रयोग) का उपयोग करता है एक अनुप्रयोग चला रहे हैं तो अपने विलंबता एक दूसरे के आसपास के रुक जाता है के साथ सही मायने में भयंकर हो जाएगा, जब आपके धागे में से कोई भी किसी भी प्रगति कर सकते हैं सब। ऐसा इसलिए है क्योंकि .NET 4 सर्वर जीसी एक स्टॉप-द-वर्ल्ड जीसी है। जाहिर है, .NET 4.5 माइक्रोसॉफ्ट के पहले ज्यादातर समवर्ती सर्वर जीसी पेश करेगा।

मैं एक बार का उपयोग कर एक समवर्ती प्रणाली में सुप्तावस्था को मापने के लिए कुछ उपकरण कोड लिखा निर्मित ConcurrentBag तरह संग्रह और बड़े पैमाने पर ढेर विखंडन के कारण 32-बिट में स्मृति से बाहर चल रहा रखा क्योंकि नेट जीसी बड़ी वस्तुओं को Defragment नहीं है । मुझे सरणी-आधारित डेटा संरचनाओं को पूरी तरह से कार्यात्मक डेटा संरचनाओं के साथ प्रतिस्थापित करना था जो कि बड़े ऑब्जेक्ट हीप (LOH) पर कुछ भी होने से बचने के लिए लाखों छोटे टुकड़ों में बिखरे हुए हैं जो विखंडन का कारण बन रहे थे।

मुझे जीसी में this one जैसी बग मिली है जो जीसी को स्मृति को रिसाव करने का कारण बनती है जब तक कि सभी सिस्टम मेमोरी समाप्त नहीं हो जाती है, जहां एक विशाल जीसी चक्र में ढेर को साफ़ किया जाता है जो न केवल आपके सभी धागे बल्कि अन्य प्रक्रियाओं को रोकता है (क्योंकि प्रणाली स्वैप करने के लिए चला गया है) कई मिनट तक!

हालांकि नवीनतम .NET जीसी में "कम विलंबता" सेटिंग है, लेकिन वास्तव में यह कचरा संग्रह बंद कर देता है, इसलिए आपका प्रोग्राम स्मृति को तब तक ले जाता है जब तक कि आप एक बड़े जीसी विराम प्राप्त न करें। माइक्रोसॉफ्ट इस तरह के कामकाज पसंद करते प्रतीत होता है जो कहने की ताकत है कि "अगर आप प्रयोग योग्य विलंबता चाहते हैं तो अपना खुद का कचरा कलेक्टर लिखें"।

हालांकि, .NET जीसी आमतौर पर बहुत अच्छा होता है, और जब सावधानी से उपयोग किया जाता है, तो इससे अच्छे परिणाम प्राप्त करना संभव है। उदाहरण के लिए, मैंने हाल ही में एक गलती-सहिष्णु सर्वर लिखा है जो 0.5 मिमी से नीचे की 95% लेटेंसी के साथ औसत पर 114μs दरवाजा-से-दरवाजा विलंबता प्राप्त करता है। यह अत्याधुनिक के करीब प्रभावशाली है (here और here देखें) क्योंकि मैंने पूरे प्लेटफ़ॉर्म को केवल कुछ महीनों में F # में लिखा था। नेटवर्क ने वास्तव में .NET जीसी की तुलना में विलंबता में अधिक योगदान दिया।

+0

कुछ दिलचस्प पढ़ने की बात है, धन्यवाद! मैं आपके द्वारा पोस्ट किए गए लिंक पर भी पढ़ूंगा :) –

+1

मैं पुष्टि कर सकता हूं कि 'सस्टेन्ड लोवेटेंसी' वास्तव में जीसी बंद कर देता है। जब मैं 'आउटऑफमेमरी अपवाद' प्राप्त कर रहा था, तो यह काफी शॉक था, लेकिन पूरी तरह से यह अच्छी तरह से काम करने के लिए निकला क्योंकि मुझे इसकी आवश्यकता होने पर लगभग कोई विलंबता नहीं थी, लेकिन हर कुछ मिनटों में रोक लग सकती थी। फिर मैंने 'समवर्ती' पर वापस स्विच किया और फिर इसे बंद करने से पहले जीसी क्लीनअप को छोड़ दिया। – codekaizen

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