内存未在WPF映像中发布 [英] Memory not getting released in WPF Image

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

问题描述

我在 Canvas 中加载和卸载图片。我使用以下代码加载图像

I am loading and unloading images in Canvas. I used the below code to load the 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

图像显示正确,现在的内存消耗为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 您可以参考的创建这里这里 here


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

实际上,WPF在静态BitmapImage和Image之间保留了强大的引用,并挂了一些位图图像上的事件。因此,您应该在分配到图像之前冻结bitmapImage 。 WPF不会在冻结的bitmapImage上挂钩事件。还要设置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天全站免登陆