BitmapImage不再需要后如何释放内存?

问题描述 投票:0回答:4

首先,我将

BitmapImage
加载到位于
Image
上的
Window
控件中。 然后我使用
Image
控件,然后关闭
Window

我在一分钟内执行 2-3 次,我的内存很快就被填满,因为当窗口关闭时,由于某种原因图像不会从内存中卸载。

那么如何从

BitmapImage
控制手动卸载
Image.Source
以释放 RAM?

wpf image memory bitmapimage
4个回答
33
投票

我相信您正在寻找的解决方案位于 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();

也可以冻结位图图像:

bitmap.Freeze();

3
投票

在我的情况下,似乎位图缓存是问题所在。我之前加载位图是这样的:

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 照片查看器)并且内存保持较低水平。请注意,一旦图像实际渲染完毕,流不必保持打开状态。


0
投票

可以将该对象设置为

null
,这样BitmapImage对象就不再被引用。 在这种情况下,GC 应该负责释放资源。 您可以调用
GC.Collect
,但如果使用过于频繁,可能会影响性能。


-1
投票

您可以在窗口的

Dispose()
事件中对图像调用
Closed
。我认为也可以使用不同的缓存选项来优化内存占用。

编辑:

你不能调用Dispose(),相反,你可以考虑

BitmapCacheOption.None
。图像将直接从磁盘读取,不会缓存在内存中。

© www.soinside.com 2019 - 2024. All rights reserved.