首先,我将一个BitmapImage加载到Image控件中,该控件位于Window上。然后我使用Image控件,然后关闭Window。
我马上就做了2-3次,我的内存很快就填满了,因为当窗口关闭时,由于某种原因,图像不会从内存中卸载。
那么我如何从Image.Source控件中手动卸载BitmapImage来释放内存呢?
发布于 2014-10-24 00:19:49
我相信你正在寻找的解决方案就在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();发布于 2017-05-04 21:48:00
在我的情况下,位图缓存似乎是问题所在。我之前加载的位图如下:
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照片查看器),而且内存很低。请注意,一旦图像实际呈现,流就不必保持打开状态。
发布于 2011-12-02 15:11:31
可以将对象设置为null,以便不再引用BitmapImage对象。在这种情况下,GC应该注意释放资源。您可以调用GC.Collect,但如果使用太频繁,可能会影响性能。
https://stackoverflow.com/questions/8352787
复制相似问题