2011-12-02 164 views
11

首先,我上的WindowImage控制加載BitmapImage。 其次,我與Image控件一起工作,然後關閉Window如何在不再需要BitmapImage後釋放內存?

我做2-3次一分鐘,因爲在關閉窗口的圖像不卸載回到我的記憶很快填滿。

那麼如何卸載BitmapImageImage.Source手動控制釋放內存?

回答

16

我相信你正在尋找的解決方案是在http://www.ridgesolutions.ie/index.php/2012/02/03/net-wpf-bitmapimage-file-locking/。就我而言,我試圖找到一種在創建文件後刪除文件的方法,但似乎是解決這兩個問題的方法。

不釋放內存:

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

釋放內存,並允許要刪除的文件:

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.Freeze(); 
+0

是的,它在過去的日子裏爲我工作。 – AgentFire

+0

很好的答案,謝謝。幫了我很多。 – MDDDC

-1

您可以在窗口的Closed事件中的圖像上調用Dispose()。我認爲也可以使用不同的緩存選項來優化內存佔用。

編輯:

你不能調用Dispose(),相反,你可能會考慮BitmapCacheOption.None。圖像將直接從磁盤讀取,而不是緩存在內存中。

+0

我試圖使用新的BitmapImage(新的Uri(鏈接),新的RequestCachePolicy(RequestCacheLevel.NoCacheNoStore));'但沒有任何區別。內存仍在使用中。 – AgentFire

0

您可以將對象設置爲null,以便不再引用BitmapImage對象。 在這種情況下,GC應該注意釋放資源。 您可以撥打GC.Collect,但如果使用頻率過高,則會影響性能。

+0

即使我對「BitmapImage」的引用爲空,GC.Collect()也不會釋放資源。 – AgentFire

+0

您的參考鏈看起來如何?是否像'Image-> BitmapImage-> MemoryStream-> filestream->內存中的實際字節'那麼你必須空引用正確的對象,否則你仍然會使用內存。 – abhinav

+0

它看起來像這樣: 'Image.Source = new BitmapImage(new Uri(link));' – AgentFire

1

在我的情況下,似乎位圖緩存是問題。我以前裝載位圖是這樣的:

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; 
} 

這樣我可以通過萬噸圖像(如Windows照片查看器)和存儲週期保持低電平。請注意,圖像實際呈現後,流不必保持打開狀態。