This article describes how MemReplay is hooked into the CRYENGINE code and how it is used from there.
Chapters:
In methods that make an allocation, such as CryMalloc, MemReplay is told that it is entering an allocation method and then also told when it is leaving the method - along with the pointer and size that the allocation created. This allows MemReplay to track high level allocations such as those from a pool, as well as low-level physical allocations such as those through the CRTMalloc.
Each MEMSTAT_CONTEXT (or MEMSTAT_CONTEXT_FMT) creates a local stack object that effectively creates a new child node in the (root) context tree as seen in MemReplay. When the context is destroyed (because the function has been left), the context node is closed. The (root) context tree can be seen as a high-level annotated picture of the code paths that the game has taken.
Whenever an allocation occurs it is added to the top of the current context for that thread.
When a free occurs the allocation is removed from allocation's context. The current context is not affected.
Reallocs are just seen as a separate free and alloc.
Contexts can have a type (from the EMemStatContextTypes::Type enum) - feel free to add more, but only at the end of the enum. MemReplay relies on the order to correctly label them.
Contexts can also have an "instance" flag set (EMemStatContextFlags::MSF_Instance). When a context is entered that has this flag, a counter on that node is incremented. This allows MemReplay to calculate an average size for what conceptually should be separate instances.
The Engine code is distributed over: