OT: ImageList GDI leak

OT: ImageList GDI leak

Old forum URL: forums.lhotka.net/forums/t/1608.aspx


Massong posted on Friday, October 27, 2006

Hi,

A few weeks ago I implemented a bug tracker business object for my application. Whenever an (unhandled) exception appears on the client machine, I write all available information like the stack trace into the database (I used to write this information only into the event log of the client computer). This way I noticed some strange exceptions that were not reproducible on first look and seemed only to appear when the application runs for a long time yet:

System.Drawing.Image get_Item(Int32)
System.Windows.Forms

InvalidArgument=Value of '0' is not valid for 'index'.
Parameter name: index

   at System.Windows.Forms.ImageList.ImageCollection.get_Item(Int32 index)
...

or

Void _SerializationInvoke(System.Object, System.SignatureStruct ByRef, System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)
mscorlib

Void .ctor(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)
System.Windows.Forms

Exception has been thrown by the target of an invocation.
Loading of the ImageList did not succeed.

   at System.RuntimeMethodHandle._SerializationInvoke(Object target, SignatureStruct& declaringTypeSig, SerializationInfo info, StreamingContext context)
...

I found this old posting from 2002 that describes the problem very well:

“The ImageList saves its images using the ImageListStreamer object
(which in turn uses the win32 function ImageList_Write). When the form
is created, an ImageListStreamer object is deserialized from the
resources, which is set to the ImageList.ImageStream property. The
problem comes in during the set_ImageStream method: neither the
ImageList nor the ImageListStreamer take responsibility for freeing
the created GDI imagelist object. The ImageList explicity sets a flag
so that it does NOT free this handle. The ImageListStreamer object
does not have a finalizer (nor is it disposable), so there is no
chance to free this GDI handle.“

http://groups.google.de/group/microsoft.public.dotnet.framework.windowsforms/browse_thread/thread/8cb349189775aa36/70aa4f4c41649f62?lnk=st&q=Nate+Terpstra&rnum=7&hl=de#70aa4f4c41649f62

Even though this posting is from 2002, I have found no solution for this problem. Sure, avoiding and removing the ImageLists helps – that’s what I did, but I have a few Treeviews and Listviews, where this isn’t possible.

Has anybody else recognized this strange behaviour? What have you done against it?

Thanks,
Christian

PS: Visual Studio 2005

Brian Criswell replied on Friday, October 27, 2006

Does this only happen when you set up the ImageList in the designer?

Massong replied on Friday, October 27, 2006

Yes, I've created all this ImageLists in the designer. According to the posting the ImageList must contain at least one image. I think this behaviour wouldn’t appear, if I created only empty ImageLists in the designer and filled them in code.

Massong replied on Friday, October 27, 2006

I have removed all ImageLists where it was possible, and I set up the Treeview’s and Listview’s ImageLists in code now. But we use a third party print preview control and this control has got a ToolBar - and this ToolBar has got an ImageList. Avoiding ImageLists at all circumstances doesn’t seem to be possible...

Brian Criswell replied on Friday, October 27, 2006

I have ImageLists that are completely empty and are loaded at run time.  I do not think you need to avoid ImageLists at all.  Just load them at run time.

Massong replied on Monday, October 30, 2006

Thank you very much for your help.

I found the following knowledge base article about the memory leak (from October 2005):
http://support.microsoft.com/kb/813967/en-us

But I was wondering, if it really only applies to .NET 1.0 SP 2...

Copyright (c) Marimer LLC