System.Drawing.Image.Dispose() issue

Use this forum for questions on how to use .NET Memory Profiler and how to analyse memory usage.
Post Reply
Cybil74
Posts: 3
Joined: Wed Apr 22, 2009 8:45 am

System.Drawing.Image.Dispose() issue

Post by Cybil74 » Thu Apr 23, 2009 8:39 am

Hi,
while using the following environment:

.NET Memory Profiler 3.1 with Dispose Tracker activated
Visual Studio 2005
.NET Framework 2.0

and executing the following code snippet:


try
{
Image image = this.imageList1.Images[0];
image.Dispose();
}
catch
{
// Do whatever you want here to record the fact that, for whatever reason, an exception has been thrown
// between the above lines
// Image image = this.imageList1.Images[0];
// and
// image.Dispose();
// This assures that Image.Dispose() is actually called
}

I found out that .NET Memory Profiler detects an undisposed instance of the System.Drawing.Bitmap type. Looking at the allocation stacks of the Delta Undisposed Instances, it ended up to be exactly the above snippet that caused the detection.
But, as you can see, Image.Dipose() gets called for sure, a fact that is enforced by the use of the try-catch block.

So, drilling down further into the stack, I found that the line

Image image = this.imageList1.Images[0];

calls the underlying

Bitmap.FromGDIplus(IntPtr)
Image.FromHbitmap(IntPtr, IntPtr)
Image.FromHbitmap(IntPtr)
ImageList.GetBitmap(int)
ImageList.ImageCollection.get_Item(int)
(stack truncated for brevity)

So, since my code above actually disposes the Bitmap, I actually wonder if other internal routines of .NET allocate and then don't dispose other Bitmaps.

Any help from anyone?

Thank you in advance

Andreas Suurkuusk
Posts: 1025
Joined: Wed Mar 02, 2005 7:53 pm

Post by Andreas Suurkuusk » Thu Apr 23, 2009 3:25 pm

Getting a single image from an ImageList will cause a temporary bitmap to be created (in addition to the bitmap that gets returned). This bitmap is never disposed and will be reported as undisposed by the profiler. Unfortunately, there's nothing that can be done to avoid this undisposed instance (except hoping that Microsoft will fix this).

One thing to note in your example is that it might also be a bit risky to dispose the image returned by Images[0]. The documentation doesn't mention whether the same image will be returned each time it's retrieved or not. In fact, the same image will not be returned and it can be disposed, but there is a (very small) risk that this will change in a future version of the framework. Personally, I would have preferred a method like ExtractImage( int index ) instead, with clear documentation saying the it's the responsibility of the caller to Dispose the returned image.
Best regards,

Andreas Suurkuusk
SciTech Software AB

Post Reply

Who is online

Users browsing this forum: No registered users and 25 guests