Because the software is written exclusively in C we found it very important to keep things as fast and robust as possible. Memory leaks are a common destroyer of robustness and so great care was taken to eliminate them. One attack that was used was the Memory Pool API included in the APR library. Memory pool's are simple region-based memory allocators. Nearly every method in the API takes an apr_pool_t from which it will allocate any necessary memory or resources. When all the work is done, the memory pool will then be destroyed. Memory pools can also be cleared, which allows the memory already allocated to the pool to be reused and is necessary in unbounded loops and other similar situations.
Pools are also used to govern the lifetimes of various objects. Because pools are all subpools of other pools they have a hierarchy. As an example each task has its own pool that it uses during execution, and any objects allocated for use over the entire task are allocated from that pool. It's important to realize that when writing functions that take pools, it is up to the caller how long the objects allocated by the function live, not the function. If you find yourselves creating pools often, then chances are something is being done wrong. For tips and pointers on how to use pools, the Subversion team has come up with a very nice list of pointers.