GDI handles in a DotNET application
Starting with GDIView from Ray Vega's answer, I found this tip:
[DllImport("User32")]
extern public static int GetGuiResources(IntPtr hProcess, int uiFlags);
public static void GetGuiResourcesGDICount()
{
//Return the count of GDI objects.
Console.WriteLine("GDICount"+GetGuiResources(System.Diagnostics.Process.GetCurrentProcess().Handle, 0));
}
private void button1_Click(object sender, System.EventArgs e)
{
GetGuiResourcesGDICount();
}
GDIView informed that it was font objects that were being leaked; I then added calls to GetGuiResources
into our logging code to detect at which point the object creation was being triggered.
In our case, we had the text of a Label
control being updated when its parent UserControl
was hidden in a background window. This would cause GDI to leak font handles. To fix it, we changed our logic to not update the Label
unless it was currently visible on screen. To determine whether it was visible, we keep a record of when the UserControl
was last painted.
Take a look at the GDIView (it's freeware):
GDIView is a unique tool that displays the list of GDI handles (brushes, pens, fonts, bitmaps, and others) opened by every process. It displays the total count for each type of GDI handle, as well as detailed information about each handle. This tool can be useful for developers that need to trace GDI resources leak in their software.
(source: nirsoft.net)
Note that the auto-refresh is disabled by default, but it can enabled and configured for specific intervals: Options -> Auto Refresh -> Every [N] seconds
Besides the performance monitor, you can try the good old Task Manager.
Check the Process tab and click View
> Select Columns...
and check the GDI objects.