This library implements a fixed-type, dynamic-size memory pool system in C++. It enhances performance by optimizing memory allocation and deallocation through memory reuse, enabling efficient memory management. All memory pool’s creation, allocation, and deallocation are handled exclusively through the CMemoryPoolManager.
For allocation, the project provides two approaches, manual memory management and automatic memory management using a custom CSharedPtr.
⚠️ Note: The CSharedPtr used in the memory pool system is a slightly modified version of the standard one.
Manual Memory Management:
Allows explicit control over a specific memory pool and immediate deallocation, making it possible to optimize performance and manage memory flexibly.
Automatic Memory Management:
Uses CSharedPtr to safely share memory across different parts of the program, automatically freeing memory when it is no longer in use.
These two methods are designed to be used selectively based on the situation, offering flexibility in memory control as needed.
A base interface and abstract class for all memory pools. Since CMemoryPoolManager cannot manage CStaticMemoryPool<T> via void*, it relies on IMemoryPool to safely manage memory pools of T type.
Declared virtual to ensure proper destruction of derived classes like CStaticMemoryPool<T>. This allows destructors to be called correctly through a base class pointer.
CStaticMemoryPool<T> Class
Role:
A class that manages a fixed-type memory pool for objects of T type. A separate memory pool is created for each type.
The size of the memory pool is dynamically resized. The initial size can be set through the constructor of CStaticMemoryPool<T> via CMemoryPoolManager. The pool expands as needed, allocating new memory blocks of the initial size, and pushing the indices of free blocks onto the mFreeIdx stack.
The mFreeIdx stack, the indices of free blocks are managed, so the most recently freed or front-most block is prioritized for allocation. The pointer target is then constructed in-place using placement new, ensuring proper initialization and virtual function support. If no blocks are available, ExpandPool() is called.
Calls the destructor on the pointer target, then frees the memory block by adding it back to the mFreeIdx stack for reuse, optimizing memory reuse and performance.
CMemoryPoolManager Class
Role:
A singleton class that manages the creation, allocation, and deallocation of all memory pools. This class is designed to create and manage memory pools of various types.
The function deallocates the memory and returns the pointer to the pool for reuse. Even if the pool becomes unused after deallocation, it remains.
Code Breakdown
Usage Example #1 - (Manual memory management)
int main(){ // create a memory pool with a size of 100 for the Player-type CMemoryPoolManager::GetInst()->CreatePool<Player>(100); // from the Player-type memory pool, return a ptr from an available memory block. Player* ptr = CMemoryPoolManager::GetInst()->Allocate<Player>(); // return the ptr used from the memory block back to the memory pool for reuse; the pool may be `deleted` if it becomes unused after this deallocation CMemoryPoolManager::GetInst()->Deallocate(ptr); // Alternatively, use this to `prevent` the pool from being deleted even if it becomes unused after deallocation CMemoryPoolManager::GetInst()->DeallocateButKeepPool(ptr); // delete the Player-type memory pool CMemoryPoolManager::GetInst()->DeletePool<Player>(); // delete the memory pool manager instance CMemoryPoolManager::DestroyInst(); return 0;}
Example demonstrating manual memory management using the CMemoryPoolManager for the Player-type memory pool.
Usage Example #2 - (Automatic memory management)
// classes that intend to use CSharedPtr must inherit from CRefCounterint main(){ // create a memory pool with a size of 100 for the Player-type CMemoryPoolManager::GetInst()->CreatePool<Player>(100); // from the Player-type memory pool, return a ptr from an available memory block. Player* playerPtr = CMemoryPoolManager::GetInst()->Allocate<Player>(); CSharedPtr<Player> ptr1 = playerPtr; // refCount: 1 CSharedPtr<Player> ptr2 = playerPtr; // refCount: 2 ptr1 = nullptr; // refCount: 1 // automatically manage memory and return the memory to the pool ptr2 = nullptr; // refCount: 0 // delete the memory pool manager instance CMemoryPoolManager::DestroyInst(); return 0;}
Example demonstrating automatic memory management using CSharedPtr with reference counting for the Player-type memory pool.