1

I have the following piece of code that runs in a loop.

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);
      ...

Last line

BitmapPalette pallete = new BitmapPalette(bi, 256);

Sometimes throws the following exception

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

Any ideas ? I clearly have enough memory to continue execution.

user510799
  • 63
  • 5

1 Answers1

2

There are other sources of OutOfMemoryException in a managed program that don't have anything to do with running out of managed memory. The exception is also raised when it translates error codes returned by legacy native code. Like the E_OUTOFMEMORY error that can be returned by COM method calls. And relevant in your case, by GDI+. Which has only 20 distinct error codes to indicate failure, you'll find them documented in this answer. One of them is OutOfMemory.

Which can mean more than one thing. Running out of unmanaged memory, the kind used by GDI+ to store bitmap pixels is certainly a possibility. It can also mean that your process has run out of available GDI object handles, Windows imposes a handle quota of 10,000 GDI handles. Which is an enormous number btw, exceeding that quota almost always indicates a bug in the code. A handle leak. Which in the case of a managed program is almost always caused by forgetting to use the Image.Dispose() method and not having the garbage collector run often enough to allow the finalizer to release handles.

Sadly it can even be triggered by corrupted bitmap data, not likely in your case since you bomb on allocating the palette. Which indicates a handle leak, which ought to be readily visible in Taskmgr.exe, Processes tab. View + Select columns and tick GDI Objects. Keep an eye on the displayed value for your process while you test it. A steadily increasing number spells trouble, the show is over when it reaches 10,000. Also look at the "Commit size" column, that can show you trouble with consuming too much unmanaged memory.

Community
  • 1
  • 1
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536