title: BitmapData from LockBits consuming memory
body: <p>I have a C# routine to take a YUV422 bitmap and convert to RGB:</p>
  
  <pre><code>    private unsafe void YUV422toRGB(byte[] YUV422, int YUVstride, ref Bitmap RGB)
      {
          //Found http://pastebin.com/MFsDnUCq after I wrote this.
  
          int row, col, index;
          byte y1, y2, u, v;
          int r1, r2, g1, g2, b1, b2;
          int c1, c2, d, e;
          byte* RGBbytes;
          int RGBindex;
  
          //http://bobpowell.net/lockingbits.aspx
          //It looks as though this bmp guy is consuming memory to the point
          //where I must force the garbage collector or the program will crash.
          //Why?
          System.Drawing.Imaging.BitmapData bmp =
              RGB.LockBits(
              new Rectangle(0, 0, RGB.Width, RGB.Height),
              System.Drawing.Imaging.ImageLockMode.WriteOnly,
              RGB.PixelFormat);
          RGBbytes = (byte*)bmp.Scan0;
          RGBindex = 0;
          index = 0;
          for (row = 0; row &lt; RGB.Height; row++)
          {
              for (col = 0; col &lt; YUVstride; col += 4)
              {
                  u = YUV422[index + 0];
                  y1 = YUV422[index + 1];
                  v = YUV422[index + 2];
                  y2 = YUV422[index + 3];
                  index += 4;
  
                  c1 = y1 - 16;
                  c2 = y2 - 16;
                  d = u - 128;
                  e = v - 128;
  
                  int c298 = 298 * c1;
                  r1 = (c298 + 409 * e + 128) &gt;&gt; 8;
                  g1 = (c298 - 100 * d - 208 * e + 128) &gt;&gt; 8;
                  b1 = (c298 + 516 * d + 128) &gt;&gt; 8;
  
                  c298 = 298 * c2;
                  r2 = (c298 + 409 * e + 128) &gt;&gt; 8;
                  g2 = (c298 - 100 * d - 208 * e + 128) &gt;&gt; 8;
                  b2 = (c298 + 516 * d + 128) &gt;&gt; 8;
  
                  //Now for clamping.
                  //From http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax
                  //min(x, y) = y ^ ((x ^ y) &amp; -(x &lt; y))
                  //max(x, y) = x ^ ((x ^ y) &amp; -(x &lt; y))
                  //We want min(x, 255) followed by max(x, 0).
                  //The problem is that x &lt; y in C# is a bool which cannot be converted to int.
                  //But effectively, -(x &lt; y) is -1 if x &lt; y and 0 otherwise.
                  //we can do this by looking at the first bit of x-y
                  //min(x, y) = y ^ ((x ^ y) &amp; ((x - y) &gt;&gt; 31))
                  //max(x, y) = x ^ ((x ^ y) &amp; ((x - y) &gt;&gt; 31))
                  //There appears to be 10% or so speed increase with the bithack.
  
                  //r1 = Math.Max(0, Math.Min(r1, 255));
                  //r2 = Math.Max(0, Math.Min(r2, 255));
                  //g1 = Math.Max(0, Math.Min(g1, 255));
                  //g2 = Math.Max(0, Math.Min(g2, 255));
                  //b1 = Math.Max(0, Math.Min(b1, 255));
                  //b2 = Math.Max(0, Math.Min(b2, 255));
  
                  r1 = 255 ^ ((r1 ^ 255) &amp; ((r1 - 255) &gt;&gt; 31));
                  g1 = 255 ^ ((g1 ^ 255) &amp; ((g1 - 255) &gt;&gt; 31));
                  b1 = 255 ^ ((b1 ^ 255) &amp; ((b1 - 255) &gt;&gt; 31));
                  r2 = 255 ^ ((r2 ^ 255) &amp; ((r2 - 255) &gt;&gt; 31));
                  g2 = 255 ^ ((g2 ^ 255) &amp; ((g2 - 255) &gt;&gt; 31));
                  b2 = 255 ^ ((b2 ^ 255) &amp; ((b2 - 255) &gt;&gt; 31));
  
                  r1 = r1 ^ ((r1 ^ 0) &amp; ((r1 - 0) &gt;&gt; 31));
                  g1 = g1 ^ ((g1 ^ 0) &amp; ((g1 - 0) &gt;&gt; 31));
                  b1 = b1 ^ ((b1 ^ 0) &amp; ((b1 - 0) &gt;&gt; 31));
                  r2 = r2 ^ ((r2 ^ 0) &amp; ((r2 - 0) &gt;&gt; 31));
                  g2 = g2 ^ ((g2 ^ 0) &amp; ((g2 - 0) &gt;&gt; 31));
                  b2 = b2 ^ ((b2 ^ 0) &amp; ((b2 - 0) &gt;&gt; 31));
  
                  RGBbytes[RGBindex + 0] = (byte)b1;
                  RGBbytes[RGBindex + 1] = (byte)g1;
                  RGBbytes[RGBindex + 2] = (byte)r1;
  
                  RGBbytes[RGBindex + 3] = (byte)b2;
                  RGBbytes[RGBindex + 4] = (byte)g2;
                  RGBbytes[RGBindex + 5] = (byte)r2;
  
                  RGBindex += 6;
              }
          }
  
          RGB.UnlockBits(bmp);
      }
  </code></pre>
  
  <p>After the classic "hey, why does my program always crash after 30 seconds" I realized the garbage collector wasn't keeping up (I call this function 10 times a second, and the bitmaps are passed by reference throughout).</p>
  
  <p>Stepping through the code I saw that <code>RGB.LockBits</code> was the one increasing the RAM usage. I added a <code>GC.Collect()</code> every ten calls (once per second) and now things are fine.</p>
  
  <p>Am I doing something wrong here? Shouldn't <code>UnlockBits</code> clean up after itself?</p>