Uth*_*aj. 1 c# wpf memory-leaks canvas image
我正在加载和卸载图像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
Run Code Online (Sandbox Code Playgroud)
在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();
Run Code Online (Sandbox Code Playgroud)
在Image这之后被删除,但仍然记忆是20.8 MB.
任何人都可以帮助我吗?
首先,您应该通过显式调用GC.Collect()来收集内存并查看内存是否发布,因为GC集合是不确定的.在方法执行GC运行并回收内存后,您无法确定.
因此,最后将此代码显式强制GC运行以检查实际内存是否已释放:
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
Run Code Online (Sandbox Code Playgroud)
但是,创建中存在一些已知的内存泄漏问题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;
Run Code Online (Sandbox Code Playgroud)