Discussion:
Limit to GDI Handles and User Handles
(too old to reply)
Patje
2005-12-22 15:48:59 UTC
Permalink
Hi,

My software is a highly interactive application that uses lots of
windows with sub windows (a few hundred windows is not an exception).
Not all windows are visible at the same time, but at certain moments
the user must be able to quickly switch to another window so I keep the
relevant windows invisible and make them visible when needed.
Due to the structure of the software, it is not possible to decrease
the number of windows.
Nevertheless I have succeeded to decrease the used pens, brushes, ....
Cleaning up the used menu handles and icon handles is planned for the
medium- to long-term.

To prevent my application from starving the available GDI and/or User
Handles, I want to check the amount of free GDI/User handles (both for
the process as for the global system).
I found out that there is a function (GetGUIResources) where you can
get the number of used resources, but there does not seem to be a
function to get the number of free resources?
Does such a function exist or is there another way of obtaining that
value?
Or is there a simple trick to minimize the number of used resources (or
to increase the number of available resources)?

Thanks in advance.
jiangsheng[MVP]
2005-12-22 16:29:23 UTC
Permalink
Go windowless.

Reference
http://blogs.msdn.com/oldnewthing/archive/2005/03/15/395866.aspx
Post by Patje
Hi,
My software is a highly interactive application that uses lots of
windows with sub windows (a few hundred windows is not an exception).
Not all windows are visible at the same time, but at certain moments
the user must be able to quickly switch to another window so I keep the
relevant windows invisible and make them visible when needed.
Due to the structure of the software, it is not possible to decrease
the number of windows.
Nevertheless I have succeeded to decrease the used pens, brushes, ....
Cleaning up the used menu handles and icon handles is planned for the
medium- to long-term.
To prevent my application from starving the available GDI and/or User
Handles, I want to check the amount of free GDI/User handles (both for
the process as for the global system).
I found out that there is a function (GetGUIResources) where you can
get the number of used resources, but there does not seem to be a
function to get the number of free resources?
Does such a function exist or is there another way of obtaining that
value?
Or is there a simple trick to minimize the number of used resources (or
to increase the number of available resources)?
Thanks in advance.
Joseph M. Newcomer
2005-12-22 17:54:14 UTC
Permalink
I had such an app. There were as many as 50 controls on a page, and as many as 100 pages.
However, all pages were tabbed controls (some of which contained tabbed controls!). So
what I did was simply create windows on the control as needed. The trick was this: when I
created a new page, it was created from a dialog template. When the page was activated,
OnInitDialog was called. At that point, I simply iterated through the list of all child
windows, and made a list of GetWindowRect/ScreenToClient coordinates, the class of the
window, and the current contents. In the OnKillActive event, I destroyed all the windows,
having captured their contents, and in the OnSetActive event, I ran through the list
re-creating the controls. This is so fast the users never see a delay (and this was true
on 200MHz laptops, the primary target).

Hence, I was able to decrease the actual number of windows by making the windows
"virtual". This is the trick that grid controls use (which is what inspired me). So if
you have a detectable case of visibility, you can apply this technique. The idea was that
they wanted the flexibility of a grid control but the interface was not really adaptable
to a grid control environment.

Pens and brushes, with very few exceptions, should be created on an as-needed basis (the
one exception that comes to mind is the brush you need for OnCtlColor handlers.

The global system state is irrelevant; GDI resources are on a per-process basis, as are
windows. The limit I hit, by the way, was about 16K windows.
joe
Post by Patje
Hi,
My software is a highly interactive application that uses lots of
windows with sub windows (a few hundred windows is not an exception).
Not all windows are visible at the same time, but at certain moments
the user must be able to quickly switch to another window so I keep the
relevant windows invisible and make them visible when needed.
Due to the structure of the software, it is not possible to decrease
the number of windows.
Nevertheless I have succeeded to decrease the used pens, brushes, ....
Cleaning up the used menu handles and icon handles is planned for the
medium- to long-term.
To prevent my application from starving the available GDI and/or User
Handles, I want to check the amount of free GDI/User handles (both for
the process as for the global system).
I found out that there is a function (GetGUIResources) where you can
get the number of used resources, but there does not seem to be a
function to get the number of free resources?
Does such a function exist or is there another way of obtaining that
value?
Or is there a simple trick to minimize the number of used resources (or
to increase the number of available resources)?
Thanks in advance.
Joseph M. Newcomer [MVP]
email: ***@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Patje
2005-12-28 14:32:58 UTC
Permalink
Hi Joseph,
thanks for your answer.

Your idea of having virtual windows is indeed a good solution. I'll
try to translate this into an internal guideline, see if we can use
this for some of the GDI-hungry dialogs/windows we have at this moment.

I don't agree with your statement that "the global system state is
irrelevant".
If my XP system is running for more than 2 weeks, I regularly start to
get strange behaviours, like applications refuse to start up, our own
applications that complain that menus cannot be created, ... I assume
that there is some upper GDI or User limit globally to the system.

I used several utilities to find out who is taking up the resources,
but they report different values:
- GDIndicator (from
http://msdn.microsoft.com/msdnmag/issues/03/01/GDILeaks/default.aspx)
reports that my application is taking 924 GDI resources, but refuses to
report any details (all brushes, bitmaps, fonts, pallettes, ... are
zero).
- GDIObj (from www.fengyuan.com) reports that my applciation is taking
156 GDI resources and even reports the number of DC's, regions,
bitmaps, ...
- Task Manager also reports 924 GDI objects (so GDIndicator seems
correct) and 528 user objects.
- Process Explorer 9.25 (from www.sysinternals.com) also reports 924
GDI handles and 528 user handles, but also 159 'normal' handles.
What worries me most is that GDIObj reports almost 5000 GDI handles for
the process 'unknown', with PID 0 (almost 3000 bitmap handles and 1400
palette handles). Could that be someone eating up my GDI resources?

So, I think there must be some kind of system upper limit, and there
doesn't seem to be a way to find out what's left (on the system level)
or do I overlook something?

Patje.

Vipin
2005-12-22 18:31:48 UTC
Permalink
Definitely, you have resource leaks. Even the highly graphics intensive apps
don't run out of GDI resources.
Your first step is to track where the resource leaks are happening. You may
want to use the gdiobj.exe from
www.fengyuan.com to track down what type of gdi objects are leaking. You may
also use the task manger for
tracking the usage.
--
Vipin Aravind
MVP [Windows - Printing/Imaging]
Post by Patje
Hi,
My software is a highly interactive application that uses lots of
windows with sub windows (a few hundred windows is not an exception).
Not all windows are visible at the same time, but at certain moments
the user must be able to quickly switch to another window so I keep the
relevant windows invisible and make them visible when needed.
Due to the structure of the software, it is not possible to decrease
the number of windows.
Nevertheless I have succeeded to decrease the used pens, brushes, ....
Cleaning up the used menu handles and icon handles is planned for the
medium- to long-term.
To prevent my application from starving the available GDI and/or User
Handles, I want to check the amount of free GDI/User handles (both for
the process as for the global system).
I found out that there is a function (GetGUIResources) where you can
get the number of used resources, but there does not seem to be a
function to get the number of free resources?
Does such a function exist or is there another way of obtaining that
value?
Or is there a simple trick to minimize the number of used resources (or
to increase the number of available resources)?
Thanks in advance.
Continue reading on narkive:
Loading...