Today I read this blog post about how all .Net applications create three exceptions upon start; System.ExecutionEngineException, System.StackOverflowException and System.OutOfMemoryException. The reason is that if these are not allocated from the start, they cannot be created when they occur. This reminded me of when I was writing high performance daemons in C a few years ago.
In those daemons I did a number of things to prepare for the event of memory starvation. First of all I allocated some memory (a few Kb if I remember correctly). If the daemon ran out of memory it was suspended for up to a second and the memory allocation was tried again. Typically I did a handful of retries and if they all failed I released the preallocated memory, logged the error and terminated the process.
The reasoning behind this strategy was based on three assumptions. First of all, if a process cannot allocate memory it is because some other process is leaking memory (or is just using a lot of memory). Second assumption is that the offending process will terminate fairly quickly because of this. Last assumption is that if the offending process does not release memory quick enough it might be the current process that is the problem so it must terminate to let other processes proceed normally. But before termination we release some preallocated memory so that we have enough memory to log the problem.
So what about multi-threaded daemons? If one thread releases some memory another might take it all before we get the chance to log the problem. Well, in my case all daemons were single threaded. If I needed "threads" (which was rare) I forked. So that was not a problem I had to consider.