【发布时间】:2014-03-26 09:54:43
【问题描述】:
我有一个 WPF 应用程序,我通过使用 TiffBitmapEncoder 将它们转换为 TIFF 图像来保存数百个 BitmapSource。但是,我有这种奇怪的内存消耗,它经常抛出 Insufficient Memory Exception。
注意:
- 我安装了 8GB 内存。
- 图像尺寸从 10x10 到 300x300 像素不等(非常小)
这是有效的代码:
static void SaveBitmapSource(BitmapSource bitmapSource)
{
TiffBitmapEncoder encoder = new TiffBitmapEncoder();
encoder.Compression = TiffCompressOption.Zip;
BitmapFrame frame = BitmapFrame.Create(bitmapSource);
encoder.Frames.Add(frame);
using (MemoryStream ms = new MemoryStream())
{
encoder.Save(ms);
}
}
这是我记忆中的截图:
现在,如果我克隆 BitmapSource(即使只克隆一次),那么我会得到这个巨大的内存分配,从而导致内存不足异常。
static BitmapSource source2 = null;
static void SaveBitmapSource(BitmapSource bitmapSource)
{
if (source2 == null)
{
source2 = bitmapSource.Clone();
}
TiffBitmapEncoder encoder = new TiffBitmapEncoder();
encoder.Compression = TiffCompressOption.Zip;
BitmapFrame frame = BitmapFrame.Create(source2);
encoder.Frames.Add(frame);
using (MemoryStream ms = new MemoryStream())
{
encoder.Save(ms);
}
}
这是我对第二个代码示例的记忆截图
有谁知道这可能是什么原因以及如何解决?
不同之处在于第一个示例中的 BitmapSource 已渲染到屏幕上,而第二个示例中没有。我的怀疑是这可能与 GPU 和调度程序有关,可能是硬件加速转换,而第二个是在存在某种错误的 CPU 上完成的......
试过了:
- 尝试在
SaveBitmapSource()之后调用GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);,但没有成功
【问题讨论】:
-
source2有什么处理方法吗?
-
BitmapSource 没有实现 IDisposable
-
很好奇如果在函数末尾添加
GC.Collect()会影响内存使用。不是作为解决方案,而是作为诊断步骤。 -
我试过 GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);但没有任何区别
-
这是一个尖峰,而不是一个台阶。所以当然这不是内存泄漏。也与 GC 没有任何关系,这都是非托管代码。阻止您使用所有出色硬件的传统错误是强制您的程序以 32 位模式运行。您可以使用项目 + 属性、构建选项卡、平台目标设置来修复它。
标签: c# wpf memory out-of-memory bitmapencoder