The mistake that is often made is to write your own allocators so that you can have more control over how much memory is used by each system and have more visibility on what is going on. A much better way to achieve this is to use a memory profiler. There are plenty of memory profilers out there, my profiler MemPro being one example. This is a totally non-invasive way to keep track of all memory usage, and you can automatically break it down into sub systems using callstack wildcard filters. Ideally its best to keep your memory allocation and memory tracking totally separate, they have totally different requirements.
Arbitrarily dividing your memory into pools can often be detrimental because each pool will have an overhead. You can end up using much more memory than you need without actually realising it. To reduce wastage it’s always better to lump everything together, the slack is then shared by the whole system.
The only reasons for using custom allocators are CPU performance (mainly for cache coherency) and to limit fragmentation. A perfect example of this is a particle system. You want all particles contiguous in memory and you don’t want to pepper main memory with lots of short lived allocations. Another good example for partitioning off is a scripting language.
If you want an example of a general purpose malloc replacement you can have a look at my VMem allocator. It has been used in a number of shipped AAA games. It has techniques that limit fragmentation and keep the memory footprint low, something critical for console games. It’s also very fast under high thread contention. My website has extensive documentation on these techniques.