内存未在WPF映像中发布 [英] Memory not getting released in WPF Image
问题描述
我在 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屋!