2010-08-19 14 views
5

मेरे पास कोड का निम्न ब्लॉक है:मार्शल को चाहिए। फ्रिज एचजीलोबल को आखिरकार ब्लॉक में रखा जाना चाहिए ताकि यह सुनिश्चित किया जा सके कि संसाधनों का निपटारा किया जा सके?

IntPtr unmanagedPointer = Marshal.AllocHGlobal(buffer.Length); 
Marshal.Copy(buffer, 0, unmanagedPointer, buffer.Length); 
SomeCommandThatCanThrowAnException(); 
Marshal.FreeHGlobal(unmanagedPointer); 

क्या ब्लॉक को कोशिश में लपेटा जाना चाहिए, और FreeHGlobal कमांड को अंत में ब्लॉक में रखा जाना चाहिए। (यदि मध्य कमांड अपवाद फेंकता है)।

ऐसा लगता है कि आखिरकार इस मामले में मेमोरी लीक को रोका जाएगा, हालांकि उदाहरणों से मैंने ऑनलाइन पाया है, अंततः इसका उपयोग नहीं किया जाता है। शायद संसाधनों को वैसे भी स्वचालित रूप से निपटान किया जाता है (भले ही वे अप्रबंधित हैं)।

उत्तर

12

मार्शल के साथ आवंटित अप्रबंधित स्मृति। AllocHGlobal स्वचालित रूप से रिलीज़ नहीं होता है।

IntPtr unmanagedPointer = Marshal.AllocHGlobal(buffer.Length); 
try 
{ 
    Marshal.Copy(buffer, 0, unmanagedPointer, buffer.Length); 
    SomeCommandThatCanThrowAnException(); 
} 
finally 
{ 
    Marshal.FreeHGlobal(unmanagedPointer); 
} 

उदाहरण आप शायद मिल गया है संक्षिप्तता के लिए से निपटने त्रुटि को छोड़ देते हैं:

तो एक finally ब्लॉक में Marshal.FreeHGlobal डाल वास्तव में एक अच्छा विचार है।


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

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

class HGlobal : SafeBuffer 
{ 
    public HGlobal(int cb) 
     : base(true) 
    { 
     this.SetHandle(Marshal.AllocHGlobal(cb)); 
     this.Initialize((ulong)cb); 
    } 

    protected override bool ReleaseHandle() 
    { 
     Marshal.FreeHGlobal(this.handle); 
     return true; 
    } 
} 

उदाहरण:

using (var h = new HGlobal(buffer.Length)) 
{ 
    h.WriteArray(0, buffer, 0, buffer.Length); 
} 

नोट: SafeBuffer काफी जानवर है, इसलिए सावधानी की सलाह दी है।

नोट 2: सेफहैंडल्स पी/Invoke के साथ अच्छी तरह से काम करते हैं और इंटिप्टर के आसपास पूरी तरह से पारित करने की आवश्यकता को खत्म करते हैं।

सेफबफर सुरक्षित रूप से सी # से अप्रबंधित स्मृति में हेरफेर करने के लिए हैं, तो आप जो कर रहे हैं उसके आधार पर (पी/Invoke के साथ उपयोग के लिए अप्रबंधित स्मृति आवंटित करना, या सी # से अप्रबंधित स्मृति में हेरफेर करना) के आधार पर आपको बेस क्लास के रूप में सेफहैंडल या सेफ़बफर चुनना चाहिए ।

2

बिल्कुल। यह कभी स्वचालित रूप से जारी हो जाता है, यह अप्रबंधित स्मृति है।