How to dispose a Writeable Bitmap? (WPF)

Mario picture Mario · Oct 8, 2009 · Viewed 8.4k times · Source

Some time ago i posted a question related to a WriteableBitmap memory leak, and though I received wonderful tips related to the problem, I still think there is a serious bug / (mistake made by me) / (Confusion) / (some other thing) here.

So, here is my problem again:

Suppose we have a WPF application with an Image and a button. The image's source is a really big bitmap (3600 * 4800 px), when it's shown at runtime the applicaton consumes ~90 MB.

Now suppose i wish to instantiate a WriteableBitmap from the source of the image (the really big Image), when this happens the applications consumes ~220 MB.

Now comes the tricky part, when the modifications to the image (through the WriteableBitmap) end, and all the references to the WriteableBitmap (at least those that I'm aware of) are destroyed (at the end of a method or by setting them to null) the memory used by the writeableBitmap should be freed and the application consumption should return to ~90 MB. The problem is that sometimes it returns, sometimes it does not.

Here is a sample code:

// The Image's source whas set previous to this event
private void buttonTest_Click(object sender, RoutedEventArgs e)
    {
        if (image.Source != null)
        {
            WriteableBitmap bitmap = new WriteableBitmap((BitmapSource)image.Source);

            bitmap.Lock();

            bitmap.Unlock();

            //image.Source = null;
            bitmap = null;
        }
    }

As you can see the reference is local and the memory should be released at the end of the method (Or when the Garbage collector decides to do so). However, the app could consume ~224 MB until the end of the universe.

Any help would be great.

Answer

nyxtom picture nyxtom · Mar 11, 2010

Is it necessary to render the Bitmap image at the same resolution and pixels? You could create the writeablebitmap at a much lower set of pixels and call the render method. Since the writeablebitmap carries a reference to the original uielements when calling render, in this case, you are going to have 3 chunks: 1) original uielement, 2) pixels in writeablebitmap, 3) reference to copied original.

I had a similar issue with the writeablebitmap in terms of memory leaks and I fixed it from checking out this link: http://www.wintellect.com/CS/blogs/jprosise/archive/2009/12/17/silverlight-s-big-image-problem-and-what-you-can-do-about-it.aspx

If you create another writeablebitmap and copy the pixels over, then dispose of the first writeablebitmap you should see some memory release - at least I did in my scenario.