内存未在WPF映像中发布

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

在加载我的Image之前,内存消耗为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

 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。

任何人都可以帮助我吗?

首先,您应该通过显式调用GC.Collect()来测试以收集内存并查看内存是否发布,因为GC集合是不确定的。 在方法执行GC运行并回收内存后,您无法确定。

因此,最后将此代码显式强制GC运行以检查实际内存是否已释放:

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

但是,在BitmapImage创建中存在一些已知的内存泄漏问题,您可以在这里 , 此处和此处引用。

实际上,WPF在静态BitmapImage和Image之间保留了强大的参考,并在Bitmap图像上挂了一些事件。 因此,您应该在分配给图像之前冻结bitmapImage 。 WPF不会在冻结的bitmapImage上挂钩事件。 还要设置CacheOption以避免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; 

在.Net中有一种称为垃圾收集器 (GC)的东西负责管理你正在使用的内存。

  • 创建对象的实例时,需要更多内存。
  • 当您从Children集合中删除ImageSource ,实际上并没有释放任何内存,只需说“ 我不想再使用此实例 ”。

此时GC将帮助您。 它会自动检测不再使用的实例,并为您释放相关的内存。

请注意,这是一个自动过程 ,您不应该(并且您不想)负责内存管理。

你可以调用GC.Collect(); 要强制垃圾收集器立即完成其工作,您将看到内存将被释放。 注意: GC.Collect(); 应该在调试中用于检测内存泄漏,但99%的时候你不应该在生产代码中明确地调用它GC.Collect(); 是一种可以占用大量CPU时间的操作。