内存未在 WPF 图像中释放 [英] Memory not getting released in WPF Image

查看:35
本文介绍了内存未在 WPF 图像中释放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Canvas 中加载和卸载图像.我使用下面的代码加载Image.

I am loading and unloading images in Canvas. I used the below code to load the Image.

在加载我的 Image 之前,内存消耗为 14.8MB.

Before loading my Image the memory consumption is 14.8MB.

Canvas c = new Canvas();

Image im = new Image();
ImageSource src = new BitmapImage(new Uri(@"E:Capture.png"));
im.Source = src;
im.Height = 800;
im.Width = 800;

c.Children.Add(im);
homegrid.Children.Add(c); //homegrid is my grid's name

Image 显示正确,内存消耗为 20.8MB.然后我通过以下代码卸载了 Image:

The Image displayed correctly and the memory consumption now is 20.8MB. Then I unloaded the Image by the below code:

foreach (UIElement element in homegrid.Children)
{
    if (element is Canvas)
    {
        Canvas page = element as Canvas;

        if (page.Children.Count > 0)
        {
            for (int i = page.Children.Count - 1; i >= 0; i--)
            {
                if (page.Children[i] is Image)
                    (page.Children[i] as Image).Source = null;
                page.Children.RemoveAt(i);
            }
        }

        page.Children.Clear();
        page = null;
    }
}

homegrid.Children.RemoveAt(2);
InvalidateVisual();

Image 在此之后被删除,但内存仍然是 20.8 MB.

The Image gets removed after this, but the memory is still 20.8 MB.

谁能帮我解决这个问题?

Can anyone help me out this?

推荐答案

首先你应该通过显式调用 GC.Collect() 来收集内存,看看内存是否释放,因为 GC收集是不确定的.您无法确定在您的方法执行后 GC 会运行并回收内存.

First of all you should test by explicitly invoking GC.Collect() to collect memory and see that memory releases or not because GC collection is indeterministic. You can't be sure that after your method execution GC runs and reclaim the memory.

所以,最后把这段代码明确地强制 GC 运行以检查内存是否真的被释放:

So , at end put this code to explicitly force GC to run to check if actually memory is released or not:

GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();

<小时>

但是,在 BitmapImage 创建中存在一些已知的内存泄漏问题,您可以参考 这里这里此处.


However, there is some known memory leak issues in BitmapImage creation which you can refer here, here and here.

实际上,WPF 在静态 BitmapImage 和 Image 之间保持强引用,并在 Bitmap 图像上挂钩一些事件.因此,您应该在分配给图像之前冻结位图图像.WPF 不会在冻结的位图图像上挂钩事件.同时设置 CacheOption 以避免 bitmapImage 的任何缓存内存泄漏.

Actually under the covers WPF keeps a strong reference between the static BitmapImage and the Image and hook some events on Bitmap image. So, you should freeze the bitmapImage before assigning to image. WPF doesn't hook events on freezed bitmapImage. Also set CacheOption to avoid any caching memory leak of bitmapImage.

Image im = new Image();    
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.CacheOption = BitmapCacheOption.OnLoad;
bi.UriSource = new Uri(@"E:Capture.png");
bi.EndInit();
bi.Freeze();
ImageSource src = bi;
im.Source = src;
im.Height = 800;
im.Width = 800;

这篇关于内存未在 WPF 图像中释放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆