2010-03-22 17 views
37

मैं चींटियों स्मृति प्रोफाइलर का उपयोग कर एक स्मृति रिसाव खोजने की कोशिश कर रहा हूँ, और मैं एक नया शब्द में सामना किया है:पिन किए गए ऑब्जेक्ट्स क्या हैं?

पिन की गई वस्तुओं।

क्या कोई मुझे एक अच्छा & यह ऑब्जेक्ट्स के बारे में सरल स्पष्टीकरण दे सकता है, मैं वस्तुओं को पिन/अनपिन कैसे कर सकता हूं, और पता लगा सकता हूं कि किसने पिन किया है?

धन्यवाद

उत्तर

44

पिन किया गया वस्तु एक ही है कि स्थानांतरित करने के लिए अनुमति नहीं है। कचरा कलेक्टर आमतौर पर स्मृति को संकुचित करता है जिसमें यह सभी वस्तुओं को "एक या अधिक क्लस्टर" में ले जाता है। यह मुक्त स्थान के बड़े हिस्से बनाने के लिए है। के रूप में वस्तु ले जाया गया है -

यह मूलतः अगर किसी और (बाहर) एक वस्तु की स्मृति पते पर एक सूचक है, इस यादृच्छिक सामग्री लेकर जा सकते हैं मतलब है।

एक वस्तु को पिन जीसी इसे स्थानांतरित नहीं करने के लिए कहता है। यह आमतौर पर बेकार है और पॉइंटर्स के साथ काम करते समय केवल समझ में आता है - जैसे PInvoke का उपयोग करते समय। कभी-कभी आपको किसी संरचना (मेमोरी लेआउट टर्म में) में कोई पता लगाने की आवश्यकता होती है, और यदि इसे कक्षा में कार्यान्वित किया जाता है, तो आपको उसे पिन करना होगा।

  • आप बाहर नहीं मिल सकता है, जो एक obiect पिन किए गए:

    ठोस जवाब देने के लिए।

  • पिनिंग फिक्स्ड स्टेटमेंट के साथ किया जाता है। यह केवल असुरक्षित कोड में अनुमति है।

की जांच:

http://msdn.microsoft.com/en-us/library/f58wzh21%28VS.80%29.aspx

+11

यह असुरक्षित होने की जरूरत नहीं है। जैसा कि आप देख सकते हैं: बफर = नया बाइट [छवि आकार]; GCHandle जीसीबफर = GCHandle.Alloc (बफर, GCHandleType.Pinned); – Pedro77

+1

इसे पूर्ण विश्वास की आवश्यकता है, हालांकि, जो असुरक्षित कोड के बराबर है। – usr

18

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

आमतौर पर कचरा कलेक्टर स्मृति में वस्तुओं को स्थानांतरित करने के स्वतंत्रता है। प्रबंधित कोड में, जैसा कि कचरा कलेक्टर सभी संदर्भों को उपयोग करने की क्षमता है, यह स्वतंत्र रूप से एक वस्तु किसी दूसरे स्थान पर पुन: मैप और फिर उस वस्तु के सभी संदर्भ अपडेट करें कि प्रक्रिया चल कोड के लिए पारदर्शी है सकते हैं। इस तरह, जीसी में कार्यक्रम की स्मृति को व्यवस्थित करने की क्षमता है और यदि आवश्यक हो तो इसे कॉम्पैक्ट करें।

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

5

आदेश वस्तुओं पिन करने के लिए आप fixed कीवर्ड का उपयोग कर सकते हैं:

तय बयान एक चल चर स्थानांतरित करने से कचरा कलेक्टर को रोकता है। तय बयान केवल एक असुरक्षित संदर्भ में अनुमति दी है।

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

हमारे लिए समाधान BitConverter वर्ग इस्तेमाल किया गया। यदि आप बिटकॉन्टर क्लास के अंतर्निहित कोड को देखते हैं, तो आप चर से बाइट प्राप्त करते समय बाइट सरणी पिन करने के लिए निश्चित कीवर्ड का उपयोग करेंगे।

4

पिन किया गया वस्तु एक स्मृति में एक सेट स्थान होता है।

आम तौर पर कचरा कलेक्टर प्रबंधित ढेर है, जो स्मृति में वस्तुओं के स्थान में परिवर्तन को संकुचित होगा। यदि आपके पास कुछ अप्रबंधित कोड है जो आपके द्वारा बनाई गई कुछ सी # ऑब्जेक्ट को संदर्भित करता है तो आप स्मृति स्थान को बिल्कुल संदर्भित करने में सक्षम होना चाहते हैं। ऑब्जेक्ट पिन करना आपको निश्चितता के साथ ऐसा करने में सक्षम बनाता है।

आप fixed बयान का उपयोग कर उन्हें बना सकते हैं: http://msdn.microsoft.com/en-us/library/f58wzh21%28VS.80%29.aspx

6

पिन की गई वस्तुओं "पिन किया गया वस्तु एक ही है कि कचरा कलेक्टर स्मृति में स्थानांतरित नहीं कर सकते है" गैर-प्रबंधित कोड के साथ संवाद करते समय उपयोग किया जाता है। प्रबंधित कोड में कचरा कलेक्टर स्मृति ब्लॉक को स्थानांतरित करने के लिए स्वतंत्र है, क्योंकि यह स्मृति ब्लॉक के सभी संदर्भों के बारे में जानता है और तदनुसार उनको अपडेट कर सकता है।

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

6

कारण आप एक वस्तु पिन सकता है यदि आप अप्रबंधित कोड को कॉल कर रहे हैं।

कचरा कलेक्टर यह एक वस्तु नहीं रह गया है आवश्यक है कि निकाल सकते हैं चलता है। यह ढेर में मुक्त स्थान का "छेद" छोड़ देता है। जीसी तब शेष वस्तुओं को एक साथ रखकर ढेर को संकलित करता है ताकि यह सुनिश्चित किया जा सके कि फ्री स्पेस एक निरंतर ब्लॉक में है (थोड़ा आपकी हार्ड डिस्क को डिफ्रैगमेंट करना)।

यह सभी संदर्भों (प्रबंधित कोड में) को किसी भी ऑब्जेक्ट को भी अद्यतन करता है जो संकलन के हिस्से के रूप में स्थानांतरित किया गया है।

यदि आप अप्रबंधित कोड (जैसे कुछ बाहरी सी ++) के साथ काम कर रहे हैं और इसे किसी ऑब्जेक्ट में पॉइंटर देते हैं, तो जीसी के लिए अप्रबंधित कोड को बताने का कोई तरीका नहीं है जिसे ऑब्जेक्ट चलाने के बाद स्थानांतरित हो गया है। इसलिए आप ऑब्जेक्ट को बाहरी कोड के साथ साझा करने के रूप में चिह्नित कर सकते हैं ताकि आपके पास पॉइंटर अमान्य बनने की समस्या न हो।

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