2011-12-02 165 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照片查看器)和存储周期保持低电平。请注意,图像实际呈现后,流不必保持打开状态。