2012-01-05 11 views
7

एक शीर्षक में पुस्तक "सी # 2010 और .NET 4 मंच" एंड्रयू ट्रोलसन द्वारा लिखित से "एक कचरा Colection मजबूर":अवांछनीय कूड़ा संग्रह

"फिर, पूरे नेट के प्रयोजन कचरा कलेक्टर हमारी तरफ से स्मृति का प्रबंधन करना है। हालांकि, कुछ दुर्लभ परिस्थितियों में, जीसी.कोलेक्ट() का उपयोग करके कचरा संग्रह को प्रोग्रामेटिक रूप से मजबूर करना फायदेमंद हो सकता है। विशेष रूप से:

• आपका आवेदन एक में प्रवेश करने वाला है कोड का ब्लॉक जिसे आप संभव कचरा संग्रह से बाधित नहीं करना चाहते हैं। ... "

लेकिन रुको! क्या ऐसा कोई मामला है जब कचरा संग्रह अवांछनीय है? मैंने कभी ऐसा कुछ नहीं देखा/पढ़ा (कोर्स के मेरे छोटे विकास अनुभव के कारण)। यदि आपका अभ्यास करते समय आपने ऐसा कुछ किया है, तो कृपया साझा करें। मेरे लिए यह बहुत ही रोचक बिंदु है।

धन्यवाद!

+7

कृपया * "कुछ दुर्लभ परिस्थितियों" * के विशेष नोट लें * और अपने कोड पर जीसी.कोलेक्ट() को छिड़काएं। –

+0

किया जाएगा! :) – Arterius

उत्तर

5

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

यह सब तब किया जाता है जब वेब एप्लिकेशन लोड होता है, और संभवतः 4-5 सेकेंड लगते हैं। ऐसा करने के बाद, मैं GC.Collect(); पर कॉल करता हूं क्योंकि मैं आने वाले HTTP अनुरोध के दौरान संभावित रूप से सभी धागे को अवरुद्ध करने के बजाय उस स्मृति को फिर से दावा करना चाहता हूं, जबकि कचरा कलेक्टर इन सभी छोटी जीवित वस्तुओं को साफ करने के लिए बाहर निकल रहा है।मुझे यह भी पता है कि अब साफ करना बेहतर है क्योंकि ढेर शायद इस समय कम खंडित है, क्योंकि मेरे ऐप ने अब तक कुछ और नहीं किया है। इससे विलंब होने से कई और ऑब्जेक्ट्स बन सकते हैं, और जीसी स्वचालित रूप से चलाए जाने पर ढेर को संपीड़ित करने की आवश्यकता होती है।

इसके अलावा, मेरे 12 वर्षों के .NET प्रोग्रामिंग में, मैंने कभी ऐसी परिस्थिति में नहीं आया जहां मैं कचरा कलेक्टर को चलाने के लिए मजबूर करना चाहता था।

7

हां, बिल्कुल एक मामला है जब कचरा संग्रह अवांछनीय है: जब कोई उपयोगकर्ता कुछ होने का इंतजार कर रहा है, और उन्हें लंबे समय तक इंतजार करना पड़ता है क्योंकि कोड कचरा संग्रह पूरा होने तक आगे नहीं बढ़ सकता है।

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

+0

व्हील आपको पता है कि यह समस्याग्रस्त नहीं है, यहां तक ​​कि परिदृश्यों से भी दुर्लभ है जहां आप चाहें ... –

+0

@ टोनी होपकिन्सन: यह अपेक्षाकृत दुर्लभ है, लेकिन इसकी अनदेखी नहीं है। अधिक सटीक रूप से, आप अच्छी तरह से जानते हैं कि यह जल्द से जल्द * कम * समस्याग्रस्त है। –

+0

ये हमेशा नियमों को तोड़ने का एक कारण है, बहस नहीं करते कि आपको ऐसा कभी नहीं करना चाहिए, बस उन्हें तोड़ने से पहले, आपको उन्हें समझना चाहिए, ताकि आप उन्हें प्रभावी ढंग से तोड़ सकें। –

1

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

3

अनुशंसा यह है कि आपको अपने कोड में स्पष्ट रूप से Collect पर कॉल नहीं करना चाहिए। क्या आप परिस्थितियों को ढूंढ सकते हैं जहां यह उपयोगी है?

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

गलत बिंदु पर Collect पर कॉल करने से आपका प्रदर्शन खराब हो जाएगा। इससे भी बदतर, इस पर भरोसा करने के लिए आपका कोड बहुत नाजुक बनाता है। Collect पर कॉल करने के लिए आवश्यक दुर्लभ परिस्थितियों को लाभकारी, या आखिर में हानिकारक नहीं, को कोड में एक साधारण परिवर्तन के साथ पूरी तरह से पूर्ववत किया जा सकता है, जिसके परिणामस्वरूप अप्रत्याशित ओओएम, आलसी प्रदर्शन और ऐसा परिणाम होगा।

2

मैं प्रदर्शन माप से पहले इसे कॉल करता हूं ताकि जीसी परिणामों को गलत साबित न करे।

object doesItLeak = /*...*/; //The object you want to have tested 
WeakReference reference = new WeakRefrence(doesItLeak); 
GC.Collect(); 
GC.WaitForPendingFinalizers(); 
GC.Collect(); 

Assert.That(!reference.IsAlive); 

उन इसके अलावा, मैं एक स्थिति है जिसमें यह वास्तव में मददगार होगा सामना नहीं किया था:

एक अन्य स्थिति मेमोरी लीक के लिए यूनिट परीक्षण परीक्षण कर रहे हैं।
विशेष रूप से उत्पादन कोड में, GC.Collect कभी भी IMHO नहीं पाया जाना चाहिए।

1

आपका एप्लिकेशन उस कोड के ब्लॉक में प्रवेश करने जा रहा है, जिसे आप संभावित कचरा संग्रह से बाधित नहीं करना चाहते हैं। ...

एक बहुत संदिग्ध तर्क (जिसे फिर भी बहुत उपयोग किया जाता है)।

विंडोज रीयल टाइम ओएस नहीं है। आपका कोड (थ्रेड/प्रोसेस) हमेशा ओएस शेड्यूलर द्वारा पूर्व-खाली किया जा सकता है। आपके पास सीपीयू की गारंटीकृत पहुंच नहीं है।

तो यह नीचे उबलता है: जीसी-रन के लिए समय समय-स्लॉट (~ 20 एमएस) की तुलना में कैसे होता है?

इसके बारे में बहुत कम कठिन डेटा उपलब्ध है, मैंने कुछ बार खोज की।

अपने स्वयं के अवलोकन (बहुत अनौपचारिक) से, एक जीन -0 संग्रह < 40 एमएस है, आमतौर पर बहुत कम होता है। एक पूर्ण जीन -2 ~ 100 एमएस में शायद चला सकता है, शायद अधिक।

तो जीसी द्वारा बाधित होने का 'जोखिम' एक अन्य प्रक्रिया के लिए बाहर निकलने के रूप में परिमाण के समान क्रम का है। और आप बाद वाले को नियंत्रित नहीं कर सकते हैं।

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