template<typename TAllocator>
class alib::monomem::TMonoAllocator< TAllocator >
- Important Note
- Please consult the Programmer's Manual of ALib module ALib Monomem for an introduction into the rather complex topic of monotonous allocation and how to use this class.
- General Behavior
- Implements a monotonic allocator. Allocates a series of bigger memory buffers and offers sequential allocation of portions of those.
With construction, an initial memory buffer is received from the chained allocator. The size of this buffer is defined with the constructor parameter initialBufferSizeInKB. With each necessary allocation of a next buffer, this value can be increased, according to the optional parameter bufferGrowthInPercent, which defaults to 200
, resulting in doubling the size of each next buffer.
If an invocation of one of the allocation methods requests memory bigger than the remaining space in the actual (last) buffer, then a new buffer is created and made the actual buffer. The remaining space of the former actual buffer will not be used for future allocations and is wasted in this respect.
- Oversized Allocations
- If a requested allocation size exceeds what would be the size of the next buffer, then a new buffer of the extended size is created. The next allocation will then create a new buffer which continues the originally defined buffer growth path. In other words:
- Oversized allocations are allowed, and
- the next buffer's size after an oversized allocation will use the size of the last non-oversized buffer as the base value for calculating the next size.
- Note
- While accepted, oversized allocations should still be avoided, because the current buffer will not be used for further allocations. This is a design decision, allowing a more efficient implementation of this class. Former implementations kept the current buffer as the actual buffer, when an oversized allocation occured, but this feature was dropped.
- Resetting
- The allocator can be reset to a certain state (see TakeSnapshot and Reset), which disposes all memory behind the snapshot. Disposed complete buffers will not be freed, but "recycled" with future allocations.
If nested snapshots are used in the right places, further gains in execution performance can be achieved.
- External Allocation of the First Buffer
- Special constructors of this type allow to pass an existing first buffer for usage. This allows two fundamental concepts:
- The first buffer might be stack-memory, which can lead to further (sometimes dramatical) performance improvements.
This feature is leveraged by type TLocalAllocator.
- The first buffer might contain not only already emplaced objects, but even the TMonoAllocator itself. We name this a "self-contained monotonic allocator".
This feature is leveraged by type TSharedMonoVal.
- Debug Features
- Depending on the compiler-symbol ALIB_DEBUG_MEMORY, some metrics on instances of this class become available. Those might for example be helpful to find a reasonable value for constructor parameters initialBufferSize and bufferGrowthInPercent.
- See also
-
- Template Parameters
-
Definition at line 292 of file monoallocator.inl.
|
template<typename TRequires = lang::AllocatorMember<TAllocator>>
requires std::default_initializable<TRequires> |
| TMonoAllocator (const char *dbgName, detail::Buffer *pInitialBuffer, size_t pInitialBufferSizeInKB, unsigned int pBufferGrowthInPercent=200) |
|
template<typename TRequires = lang::AllocatorMember<TAllocator>>
requires std::default_initializable<TRequires> |
| TMonoAllocator (const char *dbgName, size_t pInitialBufferSizeInKB, unsigned int pBufferGrowthInPercent=200) |
|
template<typename TRequires = lang::AllocatorMember<TAllocator>>
requires std::default_initializable<TRequires> |
| TMonoAllocator (const char *dbgName, std::nullptr_t) noexcept |
|
| TMonoAllocator (const char *dbgName, TAllocator &pAllocator, detail::Buffer *pInitialBuffer, size_t pInitialBufferSizeInKB, unsigned int pBufferGrowthInPercent=200) |
|
ALIB_DLL | TMonoAllocator (const char *dbgName, TAllocator &pAllocator, size_t pInitialBufferSizeInKB, unsigned int pBufferGrowthInPercent=200) |
|
| TMonoAllocator (const TMonoAllocator &)=delete |
| Not copyable.
|
|
| TMonoAllocator (TMonoAllocator &&)=delete |
| Not movable.
|
|
ALIB_DLL | ~TMonoAllocator () |
| Destructor. Disposes all memory allocated with ChainedAllocator.
|
|
|
void * | allocate (size_t size, size_t alignment) |
|
void * | reallocate (void *mem, size_t oldSize, size_t newSize, size_t alignment) |
|
void | free (void *mem, size_t size) const |
|
template<typename TSize> |
void | dbgAcknowledgeIncreasedAllocSize (void *, TSize) const |
|
lang::AllocatorInterface< TMonoAllocator > | operator() () |
|
constexpr bool | allowsMemSplit () noexcept |
|
|
Snapshot | TakeSnapshot () |
|
ALIB_DLL void | Reset (Snapshot snapshot=Snapshot()) |
|
void | Reset (size_t firstObjectSize, size_t firstObjectAlignment) |
|
|
ALIB_DLL void | GetStatistics (Statistics &result) |
|
void | DbgLock (bool onOff) noexcept |
|
detail::Buffer * | DbgGetBuffer () noexcept |
|
const detail::Buffer * | DbgGetBuffer () const noexcept |
|
template<typename TSize> |
void | dbgCheckMemory (void *mem, TSize size) |
|
const DbgStatistics & | DbgGetStatistics () const |
|
| AllocatorMember ()=delete |
| Deleted default constructor. (The allocator has to be given with construction)
|
|
| AllocatorMember (TAllocator &pAllocator) noexcept |
|
AllocatorInterface< TAllocator > | AI () const noexcept |
|
TAllocator & | GetAllocator () const noexcept |
|
template<typename TAllocator>
template<typename TRequires = lang::AllocatorMember<TAllocator>>
requires std::default_initializable<TRequires>
Special constructor that is not initializing this type. This can be used if a value of this type is required, but only later it becomes known what the initial buffer size and growth factor is to be.
Method IsInitialized can be used to determine if an allocator was initialized on construction. If not, a placement-new calling a decent constructor is to be performed before construction.
- See also
- Chapter 10.3 Changing the Default Size of the Programmer's Manual of module ALib Monomem.
- Parameters
-
dbgName | Has to be specified with debug-compilations only. Use macro ALIB_DBG to pass a constant. |
- Template Parameters
-
TRequires | Defaulted template parameter. Must not be specified. |
template<typename TAllocator>
template<typename TRequires = lang::AllocatorMember<TAllocator>>
requires std::default_initializable<TRequires>
alib::monomem::TMonoAllocator< TAllocator >::TMonoAllocator |
( |
const char * | dbgName, |
|
|
size_t | pInitialBufferSizeInKB, |
|
|
unsigned int | pBufferGrowthInPercent = 200 ) |
Constructor. A first memory buffer is allocated from ChainedAllocator.
Parameter bufferGrowthInPercent determines the growth of memory buffers. The size of a next buffer is calculated as: newSize= (previousSize * bufferGrowthInPercent) / 100
- Parameters
-
dbgName | Has to be specified with debug-compilations only. Use macro ALIB_DBG to pass a constant. |
pInitialBufferSizeInKB | The size in kB (1024 bytes) of the first memory buffer used for the allocator itself as well as for the first allocations. |
pBufferGrowthInPercent | Optional growth factor in percent, applied to each allocation of a next buffer size in respect to its previous size. Defaults to 200 , which doubles the buffer size with each next internal buffer allocation. |
- Template Parameters
-
TRequires | Defaulted template parameter. Must not be specified. |
template<typename TAllocator>
template<typename TRequires = lang::AllocatorMember<TAllocator>>
requires std::default_initializable<TRequires>
Same as Create(const char*, TAllocator&, size_t, unsigned int), but misses the allocator parameter. Used with chained allocators that are default-constructible (e.g., HeapAllocator):
- Parameters
-
dbgName | Has to be specified with debug-compilations only. Use macro ALIB_DBG to pass a constant. |
initialBufferSizeInKB | The size of memory the buffers allocated in kilobytes. |
bufferGrowthInPercent | Optional growth factor in percent, applied to the buffer size with each next buffer allocation. Values provided should be greater than 100.
Defaults to 200 , which doubles buffer size with each next internal buffer allocation. |
- Template Parameters
-
TRequires | Defaulted template parameter. Must not be specified. |
- Returns
- A pointer to an instance of this type MonoAllocator residing in its first created buffer.
template<typename TAllocator>
This static method creates an object of this type inside "itself", aka inside its first allocated buffer. Instances created with this method have to be deleted by only invoking the destructor, e.g., using Destruct.
Method Reset must not be called using its default parameter when an instance of this type was created by this method. Instead, if reset operations are desired, a snapshot has to be taken (see method TakeSnapshot) right after the invocation of this method and maybe other initial members that should survive a reset, which then has to be passed to method Reset.
Alternatively, if only the monotonic allocator should survive the reset, overloaded method Reset(size_t, size_t) might be used, passing sizeof(TMonoAllocator<T>)
and alignof(TMonoAllocator<T>)
as parameters.
- Parameters
-
dbgName | Has to be specified with debug-compilations only. Use macro ALIB_DBG to pass a constant. |
pAllocator | The allocator used for creating the first buffer. |
initialBufferSizeInKB | The size of memory the buffers allocated in kilobytes. |
bufferGrowthInPercent | Optional growth factor in percent, applied to the buffer size with each next buffer allocation. Values provided should be greater than 100.
Defaults to 200 , which doubles buffer size with each next internal buffer allocation. |
- Returns
- A pointer to an instance of this type MonoAllocator residing in its first created buffer.
template<typename TAllocator>
Lock or unlock this allocator. If locked, an ALib assertion is raised if allocations are performed. This can be quite useful to detect allocations with an allocator that is shared between different code entities and to enforce certain allocation contracts.
With release-compilations, this method is empty and optimized out.
- See also
- Chapter 11.4 Debugging of the Programmer's Manual of this ALib Module.
- Parameters
-
Definition at line 928 of file monoallocator.inl.
template<typename TAllocator>
This method has to be called before destruction of an instance, in the case that instance was allocated using a special version of the constructors that accept an external Buffer. This will remove the initially given buffer from the list of buffers, and thus this buffer not be deleted. Only if the memory was simply heap-allocated using std::malloc
, C++ new operator
, or HeapAllocator, and if the memory is intended to be freed, this method may not be called. As a sample, class TLocalAllocator, which uses stack-memory for the first buffer, will call this method in its destructor.
- Attention
- If this method is not called when needed, this leads to undefined behavior.
- If this method is called without the provision of an external buffer on construction, a memory leak occurs. (The first buffer this allocator allocated, will not be freed.)
- After this method has been invoked, the instance becomes unusable and is to be destructed in a next step.
Note that as an exception to the rule, this method's name starts with a lowercase letter as if it was protected, while it has to be public.
Definition at line 167 of file monoallocator.t.inl.
template<typename TAllocator>
This internal allocation method is called by the allocation interface methods, in case the current request cannot be trivially satisfied.
Implements the overall strategy of this class in respect to oversized blocks, recycling of blocks, etc.
- Parameters
-
size | The size of the first object to allocate in the buffer. |
alignment | The allocation alignment of the first object to allocate. |
- Returns
- A pointer to the memory allocated for the object.
Definition at line 185 of file monoallocator.t.inl.
template<typename TAllocator>
Grows a piece of memory. If a new allocation had to be performed, the existing data is copied. Note that this allocator implementation never shrinks memory, thus if oldSize is greater than newSize, the original memory is returned.
- Parameters
-
mem | The memory to reallocate. |
oldSize | The current size of mem. |
newSize | The now required size of mem in bytes. With this allocator this is not an input/output parameter. |
alignment | The (minimum) alignment of the memory block to allocate in bytes. (Has to be the same as before, but this is not tested here). See Chapter 11.1 Alignment of the Programmer's Manual of this module. |
- Returns
- Pointer to the re-allocated memory block.
Definition at line 779 of file monoallocator.inl.
template<typename TAllocator>
Special version of Reset(Snapshot) which resets this allocator to the first buffer and within that, behind the first object of the given size.
This method is used by class TSharedMonoVal to avoid the need of storing a snapshot behind itself.
If the compiler-symbol ALIB_DEBUG_ALLOCATIONS is set, then all freed memory is overwritten with 0xD2
. This helps to identify invalid reset operations.
- Parameters
-
firstObjectSize | The size of the first emplaced object. |
firstObjectAlignment | The alignment of the first emplaced object. |
Definition at line 902 of file monoallocator.inl.
template<typename TAllocator>
Resets this allocator to the given Snapshot. Parameter snapshot is defaulted with a default-constructed Snapshot, which completely resets the allocator.
With a reset, the memory buffers which had been allocated after taking the given snapshot, are not released back to the operating system, but re-used with future monotonic allocations.
This method is useful in cases where some permanent objects which are allocated first have to be preserved with resets.
Note that snapshots taken after the given one become invalid. This is because class Snapshot is only a simple lightweight class that marks the currently used buffer and its fill level.
- Parameters
-
snapshot | The snapshot to reset to. |
Definition at line 82 of file monoallocator.t.inl.