2009-07-19 9 views
12

मैं MSDN पर और ग # के माध्यम से CLR पर इस समस्या के बारे में पढ़ा है।एक अप्रबंधित संसाधन के साथ GC.AddMemoryPressure का उपयोग कर की बात क्या है?

कल्पना कीजिए कि हम एक 2Mb अप्रबंधित HBITMAP आवंटित और एक 8 बाइट्स कामयाब बिटमैप यह इंगित करता हो। AddMemoryPressure साथ इसके बारे में जीसी बता अगर यह कभी नहीं वस्तु के बारे में कुछ भी करने के लिए सक्षम होने जा रहा है, के रूप में यह,, कचरा संग्रह करने के लिए अतिसंवेदनशील नहीं अप्रबंधित संसाधन के रूप में आवंटित किया जाता है इस प्रकार की बात क्या है?

उत्तर

9

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

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

संपादित करें:

ठीक है, मामले में, मैं यह कर सकता है, लेकिन यह कोई बहुत फ़र्क पड़ता है चाहते हैं, के रूप में जीसी मेरी प्रकार के बारे में एक बात करने के लिए सक्षम नहीं होगा , अगर मैं इसे सही ढंग से समझता हूं: 1) मैं अपने चर, 8 प्रबंधित बाइट्स, 2 एमबी अप्रबंधित बाइट घोषित करता हूं। मैं इसका उपयोग करता हूं, निपटान कहता हूं, इसलिए अप्रबंधित स्मृति मुक्त हो जाती है। अभी यह केवल 8 बाइट्स ओकप्पी होगा। अब, मेरी आंखों के लिए, अंत में भिखारी AddMemoryPressure और RemoveMemoryPressure में बुलाए जाने से कुछ भी अलग नहीं होता। मुझे क्या गलत हो रहा है? इस बारे में बहुत परेशान होने के लिए खेद है। - जॉर्ज ब्रैंको

मुझे लगता है कि मुझे आपकी समस्या दिखाई दे रही है।

हां, अगर आप गारंटी दे सकते हैं कि आप हमेशा Dispose पर कॉल करते हैं, तो हाँ, आपको AddMemoryPressure और RemoveMemoryPressure से परेशान करने की आवश्यकता नहीं है। कोई समानता नहीं है, क्योंकि संदर्भ अभी भी मौजूद है और प्रकार कभी एकत्र नहीं किया जाएगा।

उसने कहा, आप अभी भी पूर्णता के लिए AddMemoryPressure और RemoveMemoryPressure का उपयोग करना चाहते हैं। क्या होगा, उदाहरण के लिए, आपकी कक्षा का उपयोगकर्ता निपटान करना भूल गया?उस स्थिति में, मान लीजिए कि आपने निपटान पैटर्न को सही तरीके से कार्यान्वित किया है, तो आप अंतिम रूप से अपने अप्रबंधित बाइट्स को पुनः प्राप्त कर देंगे, यानी जब प्रबंधित ऑब्जेक्ट एकत्र किया जाता है। उस स्थिति में, आप चाहते हैं कि स्मृति दबाव अभी भी सक्रिय हो, ताकि ऑब्जेक्ट को पुनः दावा करने की अधिक संभावना हो।

+0

ठीक है, जिसने सवाल का जवाब नहीं दिया, lol। –

+0

मैंने लगभग बिल्कुल कहा कि स्टीवन लियोन ने क्या कहा, केवल एक अलग तरीके से। इस सवाल का जवाब कैसे नहीं दिया? – Randolpho

+0

ठीक है, वास्तव में मैंने इसे फिर से पढ़ा और मेरी पोस्ट संपादित की। –

13

यह इतना है कि जी सी संग्रह के दौरान वस्तु की वास्तविक लागत जानता है प्रदान की जाती है। यदि ऑब्जेक्ट वास्तव में प्रबंधित आकार के मुकाबले बड़ा है, तो यह त्वरित (एआर) संग्रह के लिए उम्मीदवार हो सकता है।

ब्राड अब्राम entry इसके बारे में बहुत स्पष्ट है:

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

+0

वास्तव में, अब जब मैं आपकी पोस्ट को दोबारा पढ़ता हूं तो मेरा प्रश्न अभी भी खड़ा है। मेरे बिटमैप का उपयोग करने के बाद, मैं इसे निपटाने के लिए कहूंगा, इसलिए यह वास्तव में केवल 8 बाइट मेमोरी लेगा। अगर दूसरी तरफ, मैंने निपटान नहीं किया, ठीक है, तो यह वास्तव में स्मृति के 2 एमबी ocuppies। तीसरा मामला है जहां कोई निपटान विधि नहीं है, इसलिए जीसी इसके लिए कुछ भी नहीं कर सकता है। तो, इस प्रकार के वास्तविक आकार को जानने वाला जीसी केवल स्थिति 2 में मदद करेगा। या क्या मुझे कुछ याद आ रही है? –

+0

1 मामले में, आप बिटमैप आवंटन पर GC.AddMemoryPressure और फिर GC.RemoveMemoryPressure को कॉल करना चाहते हैं जब आप मैन्युअल रूप से बिटमैप जारी करते हैं। इससे यह सुनिश्चित होगा कि ऑब्जेक्ट जीसी के आकार को सही ढंग से दर्शाता है। हालांकि, अगर यह सुनिश्चित करने का कोई तरीका है कि जीसी कभी नहीं चलती है, जबकि आपका ऑब्जेक्ट संग्रह के लिए योग्य है और बिटमैप आवंटित किया गया है, तो इन तरीकों से कोई फर्क नहीं पड़ता। –

+0

ठीक है, एक मामले में, मैं इसे कर सकता था, लेकिन इससे कोई बड़ा अंतर नहीं आएगा, क्योंकि जीसी मेरे प्रकार के बारे में कुछ नहीं कर पाएगा, अगर मैं इसे सही ढंग से समझता हूं: 1) मैं अपनी घोषणा करूंगा परिवर्तनीय, 8 प्रबंधित बाइट्स, 2 एमबी अप्रबंधित बाइट्स। मैं इसका उपयोग करता हूं, निपटान कहता हूं, इसलिए अप्रबंधित स्मृति मुक्त हो जाती है। अभी यह केवल 8 बाइट्स ocuppy होगा। अब, मेरी आंखों के लिए, अंत में भिखारी AddMemoryPressure और RemoveMemoryPressure में बुलाए जाने से कुछ भी अलग नहीं होता। मुझे क्या गलत हो रहा है? इस बारे में बहुत परेशान होने के लिए खेद है। –

2

इसे इस तरह से रखें, अभी भी 8 बाइट प्रबंधित वस्तुओं को मानते हुए प्रत्येक 2 एमबी अप्रबंधित छवि का जिक्र करते हैं। सैकड़ों या हजारों छोटी प्रबंधित वस्तुओं को इकट्ठा करने से पहले जीसी लंबे समय तक इंतजार कर सकता है, क्योंकि वे बहुत छोटे हैं। इसका मतलब यह होगा कि सैकड़ों या हजारों जुड़े 2 एमबी अप्रबंधित भाग भी जिंदा रहेंगे, हटाने का इंतजार कर रहे हैं। यह एक बड़ी समस्या बन सकता है। कन्स्ट्रक्टर में 2 एमबी मेमोरी प्रेशर जोड़कर आप जीसी को सोचेंगे कि प्रबंधित ऑब्जेक्ट 8 बाइट्स बड़ा नहीं बल्कि 8 बाइट्स + 2 एमबी है। इससे पहले संग्रह के तरीके को ट्रिगर किया जाएगा।

निकालें कॉल को न भूलें।

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

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