BitmapPalette内存不足异常

时间:2012-05-30 09:00:30

标签: c# wpf winforms png gdi+

我有一段循环运行的代码。

public void Test(Bitmap bmp)
{
   FormatConvertedBitmap fBitmapSource = new FormatConvertedBitmap();
   PngBitmapEncoder pngBitmapEncoder = new PngBitmapEncoder();
   BitmapImage bi = new BitmapImage();

   using (MemoryStream ms = new MemoryStream())
   {
      bmp.Save(ms, ImageFormat.Png);
      bmp.Dispose();
      bmp = null;

      bi.BeginInit();
      bi.StreamSource = ms;
      bi.EndInit();

      BitmapPalette pallete = new BitmapPalette(bi, 256);
      ...

最后一行

BitmapPalette pallete = new BitmapPalette(bi, 256);

有时会抛出以下异常

Insufficient memory to continue the execution of the program.at System.Windows.Media.Imaging.BitmapPalette..ctor(BitmapSource bitmapSource, Int32 maxColorCount)

有什么想法吗?我显然有足够的内存来继续执行。

1 个答案:

答案 0 :(得分:2)

托管程序中还有其他OutOfMemoryException源,与托管内存耗尽没有任何关系。当它转换旧版本机代码返回的错误代码时,也会引发异常。就像COM方法调用可以返回的E_OUTOFMEMORY错误一样。与您的情况相关,由GDI +。其中只有20个不同的错误代码表示失败,您会在this answer中找到它们。其中一个是OutOfMemory。

这可能意味着不止一件事。耗尽非托管内存,GDI +用于存储位图像素的类型肯定是可能的。它还可能意味着您的进程已用完可用的GDI对象句柄,Windows强加了10,000 GDI句柄的句柄配额。这是一个巨大的数字btw,超过该配额几乎总是表明代码中的错误。手柄泄漏。在托管程序的情况下,几乎总是由于忘记使用Image.Dispose()方法而没有经常运行垃圾收集器以允许终结器释放句柄。

可悲的是,它甚至可能被损坏的位图数据触发,因为你在分配调色板时炸弹,所以不太可能。这表示句柄泄漏,应该在Taskmgr.exe,Processes选项卡中很容易看到。查看+选择列并勾选GDI对象。在测试过程中,请密切关注过程的显示值。一个稳定增加的数字意味着麻烦,当它达到10,000时,节目结束。另请查看“提交大小”列,它可以显示您在使用过多的非托管内存时遇到麻烦。