我有一段循环运行的代码。
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)
有什么想法吗?我显然有足够的内存来继续执行。
答案 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时,节目结束。另请查看“提交大小”列,它可以显示您在使用过多的非托管内存时遇到麻烦。