2011-12-02 12 views
11

सबसे पहले, पर Image नियंत्रण पर BitmapImage लोड करें। दूसरा, मैं Image नियंत्रण के साथ काम करता हूं और फिर Window बंद करता हूं।बिटमैप छवि के बाद मेमोरी को कैसे मुक्त किया जाए?

मैं इसे एक मिनट में 2-3 बार करता हूं और मेरी याददाश्त बहुत तेज़ी से भर जाती है क्योंकि खिड़की बंद होने पर छवियां वापस नहीं उतारती हैं।

तोसे मैन्युअल रूप से स्मृति को मुक्त करने के लिए मैन्युअल रूप से नियंत्रण कैसे करें?

उत्तर

16

मुझे विश्वास है कि आप जो समाधान खोज रहे हैं वह http://www.ridgesolutions.ie/index.php/2012/02/03/net-wpf-bitmapimage-file-locking/ पर है। मेरे मामले में, मैं इसे बनाए जाने के बाद फ़ाइल को हटाने का एक तरीका खोजने का प्रयास कर रहा था, लेकिन यह दोनों मुद्दों का समाधान प्रतीत होता है।

अप स्मृति मुक्त नहीं करता:

var bitmap = new BitmapImage(new Uri(imageFilePath)); 

स्मृति नहीं रह जाती और फ़ाइल हटाए जाने के लिए अनुमति देता है:

bitmap.Freeze(); 
+0

हां यह पुराने दिनों में मेरे लिए काम करता था। – AgentFire

+0

ग्रेट उत्तर, धन्यवाद। मुझे बहुत मदद की। – MDDDC

-1

आप विंडो के Closed ईवेंट में छवियों पर Dispose() पर कॉल कर सकते हैं। मुझे लगता है कि अलग-अलग कैशिंग विकल्पों का उपयोग करके अपनी मेमोरी पदचिह्न को अनुकूलित करना भी संभव हो सकता है।

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

आप निपटान() फोन नहीं कर सकते हैं, बजाय, आप BitmapCacheOption.None सोच सकते हैं। छवि सीधे डिस्क से पढ़ी जाएगी और स्मृति में कैश नहीं की जाएगी।

+0

मैंने 'नया बिटमैप छवि (नया उरी (लिंक), नया RequestCachePolicy (RequestCacheLevel.NoCacheNoStore)) का उपयोग करने का प्रयास किया है, लेकिन इसमें कोई अंतर नहीं है। मेमोरी अभी भी उपयोग में है। – AgentFire

0

आप ऑब्जेक्ट को null पर सेट कर सकते हैं, ताकि बिटमैप छवि ऑब्जेक्ट का संदर्भ नहीं दिया जा सके। इस स्थिति में, जीसी को संसाधनों को मुक्त करने का ख्याल रखना चाहिए। आप GC.Collect पर कॉल कर सकते हैं लेकिन यह अक्सर उपयोग किए जाने पर प्रदर्शन को प्रभावित कर सकता है।

+0

'जीसी.कोलेक्ट()' संसाधनों को मुक्त नहीं करता है, भले ही मैं 'बिटमैप छवि 'के संदर्भ को नल दूं। – AgentFire

+0

आपकी संदर्भ श्रृंखला कैसी दिखती है?क्या यह 'छवि-> बिटमैप छवि-> मेमोरीस्ट्रीम-> फाइलस्ट्रीम-> स्मृति में वास्तविक बाइट्स' की तरह कुछ है, तो आपको सही ऑब्जेक्ट को निरस्त करना होगा, अन्यथा आप अभी भी स्मृति का उपयोग करेंगे। – abhinav

+0

ऐसा लगता है: 'छवि। स्रोत = नया बिटमैप छवि (नया उरी (लिंक)); – AgentFire

1

:

var bitmap = new BitmapImage(); 
var stream = File.OpenRead(imageFilePath); 
bitmap.BeginInit(); 
bitmap.CacheOption = BitmapCacheOption.OnLoad; 
bitmap.StreamSource = stream; 
bitmap.EndInit(); 
stream.Close(); 
stream.Dispose(); 

वैकल्पिक रूप से, यह भी BitmapImage फ्रीज मेरी स्थिति में ऐसा लगता है कि बिटमैप कैशिंग मुद्दा था। मैं पहले इस तरह बिटमैप लोड हो रहा था:

Bitmap bitmap = new Bitmap(); 

using(var stream = new FileStream(...)) 
{ 
    bitmap.BeginInit(); 
    bitmap.CacheOption = BitmapCacheOption.OnLoad; 
    bitmap.StreamSource = stream; 
    bitmap.EndInit(); 
} 

bitmap.Freeze(); 
image.Source = bitmap; 

लगातार image.Source उसी तरह सिर्फ स्मृति का निर्माण किया, मैन्युअल रूप से कचरा संग्रहण वास्तव में मदद नहीं कर रहा था के लिए मजबूर की जगह।

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

Stream mediaStream; 

void DisposeMediaStream() 
{ 
    if (mediaStream != null) 
    { 
     mediaStream.Close(); 
     mediaStream.Dispose(); 
     mediaStream = null; 
     GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true); 
    } 
} 

void Update() 
{ 
    DisposeMediaStream(); 

    var bitmap = new BitmapImage(); 
    mediaStream = new FileStream(...); 

    bitmap.BeginInit(); 
    bitmap.CacheOption = BitmapCacheOption.None; 
    bitmap.StreamSource = mediaStream; 
    bitmap.EndInit(); 

    bitmap.Freeze(); 
    ControlImage.Source = bitmap; 
} 

इस तरह से मैं कई छवियों (जैसे विंडोज फोटो व्यूअर) के माध्यम से चक्र कर सकता हूं और स्मृति कम रहता है। ध्यान दें कि छवि वास्तव में प्रस्तुत होने के बाद स्ट्रीम को खुला रहने की आवश्यकता नहीं है।