#include <MemoryTracker.h>
Classes | |
struct | Allocation |
struct | CategoryStats |
struct | GlobalStats |
struct | Group |
struct | GroupStats |
Public Member Functions | |
MemoryTracker () | |
~MemoryTracker () | |
void | RegisterAlloc (void *memAddress, size_t numBytes, uint32 categoryID) |
void | RegisterRealloc (void *oldAddress, void *newAddress, size_t numBytes, uint32 categoryID) |
void | RegisterFree (void *memAddress) |
void | RegisterCategory (uint32 categoryID, const char *name) |
void | Clear () |
const GlobalStats & | GetGlobalStats () const |
bool | GetCategoryStatistics (uint32 categoryID, CategoryStats *outStats) |
void | RegisterGroup (uint32 groupID, const char *name, const std::vector< uint32 > &categories) |
bool | GetGroupStatistics (uint32 groupID, GroupStats *outGroupStats) |
void | UpdateGroupStatistics () |
void | LogStatistics (bool currentlyAllocatedOnly=true) |
void | LogLeaks () |
const std::unordered_map< void *, Allocation > & | GetAllocations () const |
const std::unordered_map< uint32, Group > & | GetGroups () const |
const std::map< uint32, CategoryStats > & | GetCategories () const |
void | Lock () |
void | Unlock () |
The memory tracker, used to track memory usage. This class can be used to get detailed information about memory usage on a per category or global basis. It can also be used to track memory leaks. Internally it does not use any of MCore's functionality so that it does not polute the memory usage statistics. The tracker is multithread safe, so you can call it in multiple threads. Also the RegisterAlloc, RegisterRealloc and RegisterFree functions do not actually perform the allocations or frees, but are purely there for statistical tracking. You can use the LogLeaks method at application shutdown to log memory leaks. To log current memory statistics you can call LogStatistics at any moment.
MCore::MemoryTracker::MemoryTracker | ( | ) |
The constructor.
MCore::MemoryTracker::~MemoryTracker | ( | ) |
The destructor.
void MCore::MemoryTracker::Clear | ( | ) |
Reset the tracker, clearing any information about its allocations and memory categories. This clears all categories as well, so it will be like no categories have been registered or internally created.
const std::unordered_map< void *, Allocation > & MCore::MemoryTracker::GetAllocations | ( | ) | const |
Get the current collection of allocations. The allocations are stored in an unordered map with the memory address as key. Keep in mind that for thread safety you should lock the memory tracker using the Lock method, while you read the returned data, after which you should call Unlock again.
const std::map< uint32, CategoryStats > & MCore::MemoryTracker::GetCategories | ( | ) | const |
Get the collection of registered categories. The categories are stored in an ordered map, ordered on category ID, which is also the key. Keep in mind that for thread safety you should lock the memory tracker using the Lock method, while you read the returned data, after which you should call Unlock again.
bool MCore::MemoryTracker::GetCategoryStatistics | ( | uint32 | categoryID, |
CategoryStats * | outStats | ||
) |
Get statistics about a given memory category. This is thread-safe and internally locks and unlocks.
categoryID | The memory category ID. |
outStats | The statistics for this given memory category. |
const GlobalStats & MCore::MemoryTracker::GetGlobalStats | ( | ) | const |
Get the global memory usage statistics. This gives information like the current memory usage in total. If you would like more detailed information about what categories use what amount of memory, use the GetCategoryStats method.
const std::unordered_map< uint32, Group > & MCore::MemoryTracker::GetGroups | ( | ) | const |
Get the collection of registered groups. The groups are stored in an unordered map with the group ID as key. Keep in mind that for thread safety you should lock the memory tracker using the Lock method, while you read the returned data, after which you should call Unlock again.
bool MCore::MemoryTracker::GetGroupStatistics | ( | uint32 | groupID, |
GroupStats * | outGroupStats | ||
) |
Get the statistics for a given group. When the given groupID does not exist, this method will instantly return and outGroupStats will remain untouched. Please keep in mind that the group statistics are not actively tracked. You need to call UpdateGroupStatistics to refresh the statistics for all groups. You can call UpdateGroupStatistics once and then call GetGroupStatistics for each group.
groupID | The unique ID of the group. |
outGroupStats | A pointer to the group statistics struct that will contain the statistics for this group. |
void MCore::MemoryTracker::Lock | ( | ) |
Lock the contents of this memory tracker using a multithread mutex.
void MCore::MemoryTracker::LogLeaks | ( | ) |
Log all current active allocations as leaks. This will log the leaking category stats as well as all individual allocations. This should be called at application shutdown. The logging will NOT output to a log file, but print the data to the debug output. This can be stdout, using printf or on Windows using OutputDebugString to display it inside the Visual Studio output window. This is thread-safe and internally locks and unlocks.
void MCore::MemoryTracker::LogStatistics | ( | bool | currentlyAllocatedOnly = true | ) |
Log information about all allocations that have been done and are currently active. The logging will NOT output to a log file, but print the data to the debug output. This can be stdout, using printf or on Windows using OutputDebugString to display it inside the Visual Studio output window. This is thread-safe and internally locks and unlocks.
currentlyAllocatedOnly | When set to true it will only log categories that currently have active allocations that haven't been freed yet. |
void MCore::MemoryTracker::RegisterAlloc | ( | void * | memAddress, |
size_t | numBytes, | ||
uint32 | categoryID | ||
) |
Register a given memory allocation. This does not perform the actual allocation but just updates the internal statistics inside the memory tracker. This is thread-safe and internally locks and unlocks.
memAddress | The memory address of the memory that just has been allocated and you want to register inside the tracker. This could be the address returned by a malloc for example. |
numBytes | The number of bytes that has been allocated. |
categoryID | The category ID of the memory. |
void MCore::MemoryTracker::RegisterCategory | ( | uint32 | categoryID, |
const char * | name | ||
) |
Register a memory category (optional). This method can be used to provide a user string based name to a given category ID. You can do this at any time. If the category does not exist, it will be automatically created. If it already exists because allocations have been done inside this category then it will simply update the existing name. This is thread-safe and internally locks and unlocks.
categoryID | The memory category identifier. |
name | The name you would like this category to have. |
void MCore::MemoryTracker::RegisterFree | ( | void * | memAddress | ) |
Register a free of a given memory address. This does not perform the release of the memory, but purely updates the statistics internally inside the tracker. This is thread-safe and internally locks and unlocks.
memAddress | The memory address of the memory that is being freed. |
void MCore::MemoryTracker::RegisterGroup | ( | uint32 | groupID, |
const char * | name, | ||
const std::vector< uint32 > & | categories | ||
) |
Register a group by providing a group ID and a list of categories that the group should track. If you make multiple calls to RegisterGroup, it will merge the categories if the same group ID is provided. So you can add new categories by caling this method as well. If the group already exists, the name will be overwritten with the one specified. This is thread-safe and internally locks and unlocks.
groupID | The ID of the group you wish to register or update. |
name | The name of the group. |
categories | The list of categories that should be added to the group tracking. |
void MCore::MemoryTracker::RegisterRealloc | ( | void * | oldAddress, |
void * | newAddress, | ||
size_t | numBytes, | ||
uint32 | categoryID | ||
) |
Register a reallocation of a given piece of memory. This does not actually perform the realloc of the memory, but just updates the statistics inside the memory tracker. This is thread-safe and internally locks and unlocks.
oldAddress | The original address of the memory that is being reallocated. When this is nullptr it will internally call RegisterAlloc instead using the newAddress as memory address. |
newAddress | The new address of the memory block after it has been reallocated. |
numBytes | The new size, in number of bytes, of the memory block that has been reallocated. |
categoryID | The category ID of the memory. |
void MCore::MemoryTracker::Unlock | ( | ) |
Unlock the contents of this memory tracker using a multithread mutex.
void MCore::MemoryTracker::UpdateGroupStatistics | ( | ) |
Update the internal statistics for all groups. This is thread-safe and internally locks and unlocks.