title: Image loading memory leak with C#
body: <p>I have a memory leak issue in my application which loads a large amount of images. I'm rather new to C#, and thought my days of memory leak issues were past. I can't figure out the problem - maybe I'm using some unmanaged modules which I'm not handle correctly? </p>
  
  <p>To illustrate my problem I've simplified the core of what causes the problem and moved this to a clean project. Note that this is all silly code which doesn't reflect the original application it came from. In the test application I have 2 buttons, triggering two events. </p>
  
  <p>Button 1 - Create: Setting an object to the datacontext. This will load the images and keep them alive by setting the object to the DataContext:</p>
  
  <pre><code>var imgPath = @"C:\some_fixed_path\img.jpg";
  DataContext = new SillyImageLoader(imgPath);
  </code></pre>
  
  <p>Button 2 - CleanUp: My understanding is that if I let go of the reference holding the SillyImageLoader which again holds the images, then this will be deleted. I also explicitly trigger garbage collection just to see immediately the amount of memory after dropping the reference. </p>
  
  <pre><code>DataContext = null; 
  System.GC.Collect();
  </code></pre>
  
  <p>When testing I'm loading a 974KB jpeg image. Holding 30 bitmap representations of this boosts the memory usage of my application from ~18MB to ~562MB. Ok. But when I hit cleanup the memory drops only to ~292MB. If I repeat Create+CleanUp I'm left with another ~250MB memory. So obviously something is still held by someone. </p>
  
  <p>Here is the SillyImageLoader-code: </p>
  
  <pre><code>namespace MemoryLeakTest
  {
      using System;
      using System.Drawing;
      using System.Windows;
      using System.Windows.Interop;
      using System.Windows.Media.Imaging;
  
      public class SillyImageLoader
      {
          private BitmapSource[] _images; 
  
          public SillyImageLoader(string path)
          {
              DummyLoad(path);
          }
  
          private void DummyLoad(string path)
          {
              const int numberOfCopies = 30;
              _images = new BitmapSource[numberOfCopies];
  
              for (int i = 0; i &lt; numberOfCopies; i++)
              {
                  _images[i] = LoadImage(path);
              }
          }
  
          private static BitmapSource LoadImage(string path)
          {
              using (var bmp = new Bitmap(path))
              {
                  return Imaging.CreateBitmapSourceFromHBitmap(
                      bmp.GetHbitmap(),
                      IntPtr.Zero,
                      Int32Rect.Empty,
                      BitmapSizeOptions.FromEmptyOptions());
              }            
          }
      }
  }
  </code></pre>
  
  <p>Any ideas? The problem seems to be with the BitmapSource. Holding only the Bitmap there is no memory leak. I am using BitmapSource to be able to set this to the Source property of an Image. Should I do this differently? If so - I'd still like to know the answer the memory leak. </p>
  
  <p>Thanks. </p>