WPF WriteableBitmap内存泄漏?

时间:2009-08-26 12:52:38

标签: wpf memory-leaks writeablebitmap

我正在试图找出如何释放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();
}

3 个答案:

答案 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而不将imagebitmap设置为null将无法清除它们,因为它们仍在本地引用,因此被视为根引用。这与WriteableBitmap没有任何关系,更多的是关于GC如何运作的问题。

如果您没有将它们设置为null并且不强制进行垃圾收集,那么一旦存在方法并且发生GC,它们将被收集。这是建议在上面强制收集你自己,因为你可能会伤害性能而不是帮助它。