I'm writing this since it took me days to figure out and all search phrases I tried to find the solution came up empty, except for people having similar problems but not finding any help themselves. I searched with combinations like limit child processes System.Diagnostics.Process Start or maximum number subprocesses windows service.
OK, I have this Windows service written in C# that spawns worker
processes. For some reason this stops working after the 60th or
70th child process (it is always the same number for a given
machine, but the numbers vary between
machines). Process.Start()
returns true
and Process.HasExited
returns false
but as
far as I can tell the worker process is never started. In
fact, Process.HasExited
will return false
after some time. The system has plenty of memory available and
there is no indication of any problem whatsoever other than the
processes not starting.
Some experiments show that I can spawn way more processes from a simple test application that I run interactively, so at least there doesn't seem to be a general limit on the number of children allowed (at least none I'd hit before running out of memory).
I'm not sure what lead me to check the "Allow Service to Interact with Desktop" checkbox during one test run against my real service, but suddenly I was able to start a lot more child processes. At least that finally lead me to understand what was going on.
Some Windows resources are taken from a fixed-memory-size area
named "desktop heap" and when you start a new process - even a
console application spawned with StartInfo.CreateNoWindow =
true
- you need such a resource (most likely a Window
Handle), even though most articles mentioning the desktop heap only
talk about handles for GUI elements. There are a couple of
different desktops with different default sizes for their heaps.
For a less hand waving more thorough description of
sessions, windows stations and desktops
see this.
It turns out your garden variety windows service is attached to the "Default" desktop in the window station Service-0x0-3e7$ (what an obvious name), which takes its size from a registry setting and whose size defaults to 512 kB. If you enable the "Allow Service to Interact with Desktop" checkbox, the service will be attached to a different desktop (Winsta0\Default) which takes its size from a different part of the same registry setting and defaults to 3 MB.
I'm not going to blindly recommend fiddling with the registry to bump the non-interactive desktop heap size since this has drawbacks that need to be evaluated, But at least I now understand what goes on and what my options are.
path: /en/Windows | #