2009-09-23 3 views
7

मेरे आवेदन में एक विशिष्ट समय है जब कई बड़ी वस्तुओं को एक बार में रिलीज़ किया जाता है। उस समय मैं विशेष रूप से बड़े ऑब्जेक्ट ढेर (LOH) पर एक कचरा संग्रह करना चाहता हूं।जीसी। केवल पीढ़ी 2 और बड़े ऑब्जेक्ट ढेर पर चयन करें

मुझे पता है कि आप ऐसा नहीं कर सकते हैं, आपको GC.Collect(2) पर कॉल करना होगा क्योंकि जीसी केवल पीएचएच पर ही पीढ़ी 2 संग्रह कर रहा है। हालांकि, मैं दस्तावेज में पढ़ा है कि फोन करने GC.Collect(2) अभी भी पीढ़ियों 1 पर एक जीसी चल पाएंगे और 0.

को जीसी मजबूर करने के लिए क्या यह संभव है केवल जनरल 2 एकत्रित करते हैं, और जनरल 1 या जनरल 0 शामिल नहीं ?

यदि यह संभव नहीं है, तो क्या जीसी को इस तरह से डिजाइन करने का कोई कारण है?

+0

आप ऐसा क्यों करना चाहते हैं, यानी जीन 0 या 1 से एकत्र न करें? .NET GC अपने डिवाइस पर छोड़े जाने पर सबसे अच्छा चलाता है। – thecoop

+0

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

उत्तर

12

यह संभव नहीं है। Gen0

जेन 2 जी सी एक पूर्ण संग्रह की आवश्यकता है (: जीसी डिजाइन किया जाता है कि एक पीढ़ी 2 संग्रह हमेशा भी जमा करता पीढ़ी 0 और 1.

संपादित है: आप a GC developer's blog पर इस के लिए एक स्रोत मिले , Gen1, जेन 2 और Loh! बड़े वस्तुओं हर जेन 2 जी सी भी जब जी सी LOH में जगह की कमी से शुरू हो रहा नहीं कर रहा था पर GC'ed कर रहे हैं। ध्यान दें कि वहाँ एक जीसी कि केवल बड़े वस्तुओं एकत्र करता है नहीं है।) जोसे अधिक समय लेता है 0 युवा पीढ़ी के संग्रह।

संपादित 2: एक ही ब्लॉग का उपयोग करना जीसी कुशलतापूर्वक Part 1 और Part 2 से जाहिरा तौर पर Gen0 और Gen1 संग्रह तेजी से, एक जेन 2 संग्रह की तुलना में कर रहे हैं ताकि यह मेरे लिए उचित लगता है कि केवल कर जेन 2 की नहीं होगा बहुत प्रदर्शन लाभ। एक और मौलिक कारण हो सकता है, लेकिन मुझे यकीन नहीं है। हो सकता है कि उत्तर उस ब्लॉग पर कुछ लेख में है।

+0

धन्यवाद! कृपया ध्यान दें, मैंने यह भी पूछने के लिए अपना प्रश्न संपादित किया है कि यह इस तरह से क्यों बाधित है। – DevinB

6

चूंकि सभी नए आवंटन (बड़ी वस्तुओं के अलावा) हमेशा Gen0 में जाते हैं, जीसी हमेशा निर्दिष्ट पीढ़ी और नीचे से एकत्रित करने के लिए डिज़ाइन किया गया है। जब आप GC.Collect(2) पर कॉल करते हैं, तो आप जीसी को जेन 0, जेन 1 और जेन 2 से एकत्र करने के लिए कह रहे हैं।

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

ध्यान रखें कि .NET में पीढ़ी भौतिक चीजें नहीं हैं, लेकिन जीसी प्रदर्शन बढ़ाने में मदद के लिए तार्किक अलगाव हैं। चूंकि सभी नए आवंटन Gen0 में जाते हैं, यह हमेशा पहली पीढ़ी एकत्र की जाती है। प्रत्येक संग्रह चक्र जो चलता है, संग्रह से बचने वाली निचली पीढ़ी में कुछ भी अगली उच्चतम पीढ़ी (जब तक कि जेन 2 तक नहीं पहुंच जाता) तक "प्रचारित" होता है।

ज्यादातर मामलों में, जीसी को जेन 0 एकत्र करने से परे जाने की आवश्यकता नहीं है।जीसी का वर्तमान कार्यान्वयन एक ही समय में Gen0 और Gen1 एकत्र करने में सक्षम है, लेकिन यह Gen2 या Gen1 एकत्रित होने पर Gen2 एकत्र नहीं कर सकता है। (.NET 4.0 इस बाधा को बहुत बड़ा सौदा करता है और अधिकांश भाग के लिए, जीसी जेन 2 या जेन 1 को भी एकत्रित किया जा रहा है, जबकि जीसी जेनरेट करने में सक्षम है।)

+0

आपका स्पष्टीकरण जीसी कैसे काम करता है इसका एक बड़ा अवलोकन है, लेकिन यह स्पष्ट नहीं करता है कि एक बाधा क्यों है जो * सख्ती से * जीन 1 या जीन 2 संग्रह को रोकती है। – DevinB

+2

'myVar = null' सेट करना कुछ भी पूरा नहीं करता है। Http://www.bryancook.net/2008/05/net-garbage-collection-behavior-for के नीचे देखें।एचटीएमएल – DevinB

+0

मेरा मानना ​​है कि कारण यह है कि उच्च पीढ़ियों के लिए वस्तुओं का प्रचार केवल जीसी के दौरान मूल्यांकन (और प्रभावित) होता है, इसलिए यदि आप निम्न पीढ़ियों को एकत्र नहीं करते हैं तो शायद कुछ भी नहीं (नया) है ... –

0

प्रश्न का उत्तर देने के लिए "क्यों": शारीरिक रूप से, कोई नहीं है Gen0 और Gen1 या Gen2 जैसी चीज। वे सभी वर्चुअल एड्रेस स्पेस पर एक ही मेमोरी ब्लॉक (ओं) का उपयोग करते हैं। उनके बीच भेद वास्तव में एक काल्पनिक सीमा सीमा के चारों ओर घूमकर केवल वस्तुतः बनाया जाता है।

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

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

+0

संकल्पनात्मक रूप से, यह सबसे आसान है जीन 2 चीजों को ढेर के नीचे होने के बारे में सोचने के लिए, जीएन 1 के साथ तुरंत शीर्ष पर, और शीर्ष पर gen0। पुरानी वस्तुएं हमेशा छोटी वस्तुओं से नीचे होती हैं। जब संकुचन होता है, तो प्रणाली सबसे पुरानी वस्तुओं से शुरू होने वाली पीढ़ियों (ओं) में सभी जीवित वस्तुओं के माध्यम से जाती है, और प्रत्येक वस्तु को सबसे कम उपलब्ध स्थान पर ले जाती है। "जीन 2 का शीर्ष" मार्कर सबसे ऊपर की नई प्रतिलिपि बनाई गई जीन 1 ऑब्जेक्ट (अब जीन 2 में) से ऊपर सेट है। इसी तरह "जीन 1 का शीर्ष" मार्कर शीर्षतम प्रतिलिपि बनाई गई gen0 ऑब्जेक्ट से ऊपर सेट है। – supercat

+0

इन सभी का लक्ष्य gen0 से ऊपर उपलब्ध उपलब्ध स्थान को मुक्त करना है। जीन 2 को कॉम्पैक्ट करने के कारण का एक बड़ा हिस्सा जीन 1 ऑब्जेक्ट्स को नीचे जाने की इजाजत देना है; इसी तरह जीन 1 कॉम्पैक्टिंग जीन 0 ऑब्जेक्ट्स को नीचे जाने की इजाजत देता है। कुछ अजीब चाल हैं। नेट का उपयोग यह निर्धारित करने के लिए करता है कि वस्तुएं "लाइव" हैं या नहीं; अभ्यास में, उनका मतलब है कि यदि एक gen2 ऑब्जेक्ट में gen0 ऑब्जेक्ट का संदर्भ होता है, तो gen0 ऑब्जेक्ट तब तक संग्रहित नहीं होगा जब तक कि संदर्भ नष्ट नहीं हो जाता है या gen2 ऑब्जेक्ट स्वयं एकत्र किया जा सकता है। – supercat

0

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

संयोग से, यदि आप सोच रहे हैं कि सिस्टम "जानता है" कि कोई ऑब्जेक्ट नई वस्तुओं के संदर्भ में हो सकता है, तो ऑब्जेक्ट लिखा गया है, तो प्रत्येक ऑब्जेक्ट के डिस्क्रिप्टर में दो बिट्स सेट करने के लिए सिस्टम के पास विशेष कोड है। पहला कचरा प्रत्येक कचरा संग्रह पर रीसेट किया जाता है, और यदि यह अभी भी अगले कचरा संग्रह में रीसेट हो गया है, तो सिस्टम को पता चलेगा कि इसमें Gen0 ऑब्जेक्ट्स के लिए कोई संदर्भ नहीं हो सकता है (क्योंकि ऑब्जेक्ट आखिरी बार लिखा गया था और जब नहीं था पिछले संग्रह से साफ़ किया गया Gen1 या Gen2 होगा)। दूसरा जी प्रत्येक जेन 1 कचरा संग्रह पर रीसेट किया गया है और यदि यह अभी भी अगले जेन 1 कचरा संग्रह में रीसेट हो गया है, तो सिस्टम को पता चलेगा कि इसमें जेन 0 या जेन 1 ऑब्जेक्ट्स के किसी भी संदर्भ नहीं हो सकते हैं (किसी ऑब्जेक्ट्स जिसमें संदर्भ हैं, अब जेन 2 हैं) । ध्यान दें कि सिस्टम किसी वस्तु को लिखी गई जानकारी को नहीं जानता या परवाह करता है कि क्या Gen0 या Gen1 संदर्भ शामिल है। एक अनजान ऑब्जेक्ट को लिखते समय आवश्यक जाल महंगा होता है, और यदि ऑब्जेक्ट लिखे जाने पर हर बार इसे संभालना होता है तो प्रदर्शन में काफी बाधा आती है। इससे बचने के लिए, जब भी कोई लिखता है, तब वस्तुओं को टैग किया जाता है, ताकि अगली कचरा-संग्रह से पहले कोई भी अतिरिक्त लेखन बिना रुकावट के आगे बढ़ सके।

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