After a few weeks Delphi applications running on Windows Server (2008 or later) will fail to start or create new windows with error 8: Not enough storage is available to process this command.
Possible Cause 1: Desktop Heap Exhaustion
Session 0 which service applications are running in gets allocated substantially less desktop heap than interactive sessions, so you might be running out of it. There is a system event log entry with event ID 243 or 244 when the desktop heap gets exhausted.
By increasing the values in the SharedSection part of the data in registry value “Windows” in key “HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems”, you can allocate more to the service session, as described in this Microsoft support article or this Stack Overflow answer.
Note that Microsoft’s Desktop Heap Monitor tool no longer works on current versions of Windows Server.
Possible Cause 2: Atom Leak
Applications compiled with Delphi XE2 or earlier call RegisterWindowMessage in the initialization section of Controls.pas to allocate a unique window message ID. This takes up one slot in the session’s atom table. Unfortunately, there are only around 16 000 slots in the atom table. With no way to unregister a window message, you will eventually run out of them. It has been said that on earlier versions of Windows, the counter wrapped around so you never ran out as slots got overwritten/reused.
I fixed this by editing the Controls.pas unit replacing this line
RM_GetObjectInstance := RegisterWindowMessage(PChar(ControlAtomString));
with this one
RM_GetObjectInstance := RegisterWindowMessage(PChar('DelphiRM_GetObjectInstance'));
This way all Delphi applications share the same atom instead of creating their own. There is also a more involved fix by Andreas Hausladen, but this solution sufficed for me.
Analyzing the Atom Leak
Jordi Corbilla has written the super useful Atom Table Monitor which dumps entries from the atom table. I made a C# version of it, the Atom Table Dumper, because (a) I didn’t want to diagnose issues with my Delphi applications using another Delphi application that had the same issue and (b) I needed an easier to read and process output format.
Note that your analysis tool has to run in the same session as the application getting the error.
Further note that not all of the atoms listed under RegisteredWindowMessage were necessarily allocated by RegisterWindowsMessage. RegisterClass is another function that allocates atoms in this table. However, as the documentation points out “All window classes that an application registers are unregistered when it terminates.“ so having many of them (temporarily) isn’t necessarily a problem.
After my previous visit to Museum Insel Hombroich was cut short by rain, I went again this week when the weather was nicer.
Obviously, it was a much more enjoyable visit. Museum Insel Hombroich just has this wonderful combination of art…
Powerlines I came across while walking back to Neuss. #symmetry
The museum Insel Hombroich is a large park with several sculpture, installations and architecturally interesting buildings housing artwork. Even though it is not far from Düsseldorf, it’s a bit difficult to reach by public transportation, so until yesterday I had never been there.
Unfortunately, I picked the worst possible time to go. The weather was OK when I got there, but once I had gone past the first building, what started as a drizzle soon turned into a downpour.
I walked around for a while, but couldn’t really enjoy it as I was getting soaked by the rain.
I eventually went back to the bus stop, and only then did the rain stop and the sun came out. Since there is only one every other hour, I called it a day and decided to come back some other time. Even from what little I’d seen, it’s definitely worth another visit.