In an effort to reduce resource use I have just changed a few forms from Auto Create to creating them only as required then freeing them afterwards. Those forms are only used occasionally and often never in a some usage sessions. This reduced the base GDI Objects count by about 300.
I’m not sure how to track down the occasion Out Of Resources though as I have never been able to replicate the error on my systems.
Something I’ve just noticed is that the GDI Object count creeps by 2 each time I use (create and free) one particular form. It doesn’t sound like much, but I don’t like that it seems to leak resources. I’ve checked through the code and can’t see where I’m allocating anything that’s not being freed again. How would I go about tracking that down?
Are you sure it’s a leak, it may take several to many GDI objects to ‘support’ each added image, maybe even more depending on what you can do with that image, or if it’s just a plain image vs composite.
Yes, if after deleting the image the GDI objects doesn’t go back down it’s probably a leak, but whilst it’s there it’s quite possible the increase is valid.
I’m actually looking at this issue for FinalBuilder 9 - which uses twice as many GDI objects as FinalBuilder 8 - FB8 was compiled with XE7, FB9 compiled with 11.2 - trouble is I have also updated every library so haven’t figured out what is using so many GDI objects yet - could be a library or could just be the VCL using more objects
About your GDI resources creeping up, I have struggled with this one as well. I write reasonably complex multi-threaded applications (with minimal interfaces) that process/convert sizeable incoming data & audio every 5 mn, 24/7, and while I was always happy when a FastMM4 report only found a very few GDI/unknown tiny leaks, I could never tame these, and they did creep up over months of continuous use. Not worryingly, since at least once a year an update or server reset would restart the applications and reset associated memory, but enough to annoy me.
Following the ebb and flow of these creeps over time (via GetProcessMemoryInfo()), I came to the conclusion that Windows, perhaps not surprisingly, wasn’t doing a consistent cleanup job of resources it (as opposed to Delphi) allocated.
For me, relief came from half a dozen lines of code. Once a day, at some idle time, I now ask Windows to finish cleaning up properly, and the results are quite startling:
//clear mem once a day, Windows lets it creep up over time
hProcess := OpenProcess(PROCESS_SET_QUOTA, false, GetCurrentProcessId);
SetProcessWorkingSetSize(hProcess, $FFFFFFFF, $FFFFFFFF);
After this call, memory footprint is about the size it was on first startup, all stray GDI/unknowns creeps forgotten.
Would be interesting to see if this call (or a related one) also effects such a slimming cure on handles and other niggles you mention - haven’t checked, these were never a worry in my case.
OK, I think I’ve tracked the issue down to where I’m using TCustomImageList.GetBitmap to update the Glyph and GlyphDisabled images of a tool button as the status of another process changes (paused vs not paused).
Should I be surrounding the two GetBitmap calls with something while it updates? At present I set the Glyph and GlyphDisabled to nil first, call GetBitmap for each then set the Enabled property last.
What component is BtPause? I would go and look at the code for the getter/setter on the Glyph property, what happens when set it to nil, and what happens when you read the property (which you are doing by passing as a parameter. I suspect the BtPause component is leaking bitmaps.
By clearing I meant setting to nil. That seems to be the correct way to do it going by the numerous examples I’ve seen. There doesn’t seem to be any increase in memory or objects in my testing. I’ve changed the code to only update the Glyphs when required now so we’ll see if that solves the issue of some users getting exceptions.