我正在试图找出如何释放WriteableBitmap内存。
在下一部分代码中,我填充了一个WriteableBitmap的后备缓冲区,其中包含来自“BigImage”的大量数据(3600 * 4800像素,仅用于测试) 如果我评论位图和图像等于null的行,内存不会释放,应用程序消耗约230 MB,甚至 当不再使用图像和位图时!
正如您在代码末尾所看到的,调用GC.Collect()来释放内存是必要的。
所以问题是,释放WriteableBitmap对象使用的内存的正确方法是什么? GC.Collect()是唯一的方法吗?
任何帮助都会很棒。
PS。抱歉我的英语不好。
private void buttonTest_Click(object sender, RoutedEventArgs e)
{
Image image = new Image();
image.Source = new BitmapImage(new Uri("BigImage"));
WriteableBitmap bitmap = new WriteableBitmap(
(BitmapSource)image.Source);
bitmap.Lock();
// Bitmap processing
bitmap.Unlock();
image = null;
bitmap = null;
GC.Collect();
}
答案 0 :(得分:3)
您是否正在使用.Net 3.5 SP1在Windows XP上运行测试? 如果是这样,那么这是一个已知问题,将在4.0中修复。
请参阅 http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/5d88cdf1-e992-4ad4-8f56-b5dbf92dcf1c
答案 1 :(得分:1)
通常,内存最终应根据需要自动释放。
但是,为了实现这一点,您需要确保该对象是真正未使用的:在任何地方都不存在对该对象的引用,包括“不再使用”的引用。因此,特别是,如果将WriteableBitmap和原始BitmapSource放在长寿类的变量中,则在容器出现之前不会释放它们。
此外,WPF使用保留的GFX模型:渲染时,实际上只是在如何渲染时存储指令。关于如何渲染位图的“指令”包括对位图的引用 - 所以如果你渲染一个大的位图,那么一段时间(至少只要它在屏幕上 - 即使屏幕上的版本很小)那些图像将被保留。
在实践中;只在需要它们的地方存储对这些位图的引用,并且如果它们所处的上下文是长寿的(长方法调用,或者生成带有对位图的引用的闭包的方法调用,或者长的成员)生活类)然后在不再需要它们时将它们设置为null。
无需手动释放内存; GC.Collect()应该是多余的。根据经验,仅在基准测试期间使用GC.Collect来获取内存消耗的指示和/或从干净的平板开始。通过调用GC.Collect()。
,通常会降低整体性能答案 2 :(得分:0)
强制GC而不将image
和bitmap
设置为null
将无法清除它们,因为它们仍在本地引用,因此被视为根引用。这与WriteableBitmap
没有任何关系,更多的是关于GC如何运作的问题。
如果您没有将它们设置为null
并且不强制进行垃圾收集,那么一旦存在方法并且发生GC,它们将被收集。这是建议在上面强制收集你自己,因为你可能会伤害性能而不是帮助它。