I. SGI standard space Configurator, Std::allocator
SGI also defines a configurator that complies with some of the criteria named allocator, but it does not use it itself, nor does it recommend that we use it, mainly because it is inefficient.
It just puts the C + + operator:: operator new and:: operator delete as a simple wrapper.
Second, SGI special Space Configurator, Std::alloc
Since the SGI standard space Configurator just puts C + + operators:: operator new and:: operator Delete Does a simple package without considering any efficiency enhancements.
So SGI has a special space configurator that is used by the STL Standard Template Library.
Typically, allocating memory with the new operator in C + + consists of two stages:
(1) Call:: operator new configuration memory
(2) Calling constructors to construct object content
Similarly, a delete operation includes two stages:
(1) Call destructors to refactor objects
(2) Call:: operator delete free memory
For a precise division of labor,SGI STL allocator separates two phases :
The memory configuration operation is the responsibility of the Alloc:allocate, the memory release is the responsibility of the alloc:deallocate, and the object construction operation is performed by: Contructor (), and the object is organized by::d Estroy ().
The configurator is defined in the header file <memory>, which also contains two files:
#include <stl_alloc.h> //responsible for memory space configuration and release #include <stl_construct.h> //responsible for the construction and destruction of objects
Third, STL Space configurator:
Problems solved by STL space Configurator
1: Memory Fragmentation issues (external fragmentation)
Inside fragments, external fragments introduction:
Internal fragmentation: The part of the operating system that is allocated to the requester that has not been exploited. Cause: Memory alignment (high efficiency);
Outer fragment: Memory is plentiful but does not allocate large chunks of memory. Cause: Large chunks of memory are divided into small chunks due to multiple allocations of small chunks of memory;
2. Frequent system allocation, release small block memory, call Malloc,delete system call to produce performance problems;
Implementation mechanism of STL space Configurator:
Two-tier Configurator:
Note:
When the space to be opened is greater than bytes, it is considered "large enough" to invoke a first-level configurator and call Malloc,free directly;
When the space required to open is less than bytes, considered "too small", in order to reduce the additional burden, call two-level space Configurator
Anatomy of a first-level space Configurator:
(Set_new_handler mechanism)
/***************************************************************************** function Description: First-Class Space Configurator class/function: Template<int Inst> class __mallocalloctemplate; Introduction: Call the handle handler function immediately after a memory allocation failure by calling Malloc/free directly ***************************************** /typedef void (*alloc_oom_fun) (); Handle handled after memory allocation failure handler type Template<int Inst>class __mallocalloctemplate{private:static alloc_oom_fun __ Smallocallocoomhandler; Static void* Oommalloc (size_t N)//mimic C + + set_new_handler Mechanism {Alloc_oom_fun handler = __smallocallocoomhand Ler void* result; for (;;) Loop until the memory allocation succeeds {if (handler = = 0)//check whether set processing handler {cout << ou T of memory "<< Endl; Exit (-1); } handler (); Call the client's own memory management function to free memory result = malloc (n); if (result)//assignment succeeds return result; }} static void* Oomrealloc (Void*p, size_t N) {Alloc_oom_fun handler = __smallocallocoomhandler; void* result; for (;;) Loop until the memory allocation succeeds {if (handler = = 0)//check whether set processing handler {cout << ou T of memory "<< Endl; Exit (-1); } handler (); Call the client's own memory management function to free memory result = Remalloc (n); if (result)//assignment succeeds return result; }}public:static void* Allocate (size_t N)//Direct call to malloc {void* result = malloc (n); return result = = 0? Oommalloc (n): result; } static void Deallocate (void* p)//Direct free (p); } static void *reallocate (void*p,size_t new_sz) {void* result = ReAlloc (P, NEW_SZ); return result = = 0? Oomrealloc (P, NEW_SZ): result; } static void (*setmallochandler (void (*f))) ()//reset handle Handler {alloc_oom_fun result = __smallocallocoomhand Ler __smallocallocoomhandler = f; return result; }};//Initialize the handle function pointer of the failed handler for allocating memory Template<int Inst>alloc_oom_fun __mallocalloctemplate<inst>::__ Smallocallocoomhandler = 0;
Second-level Space Configurator:
Template<bool threads, int inst>class __defaultalloctemplate{public:enum{__align = 8}; Arrange datum values (also arranged intervals) enum{__max_bytes = 128}; Maximum value enum{__nfreelists = __max_bytes/__align}; Arrange chain size static size_t round_up (size_t bytes) {return (bytes + __align-1 & ~ (__align-1)); Memory with 8 alignment} static size_t Freelist_index (size_t bytes) {return (bytes + __align-1)/__align-1); Returns the subscript in the free list} Union Obj {Union obj* _freelistlink; Pointer to next memory block Char _clientdata[1]; /* The client sees this.*/}; Static obj* volatile _freelist[__nfreelists]; Free list static char* _startfree; Memory pool start address static char* _endfree; Memory pool End Address static size_t _heapsize; Memory pool capacity//get memory from memory pool INSERT into free list static void* refill (size_t N); Allocates memory from the memory pool static char* Chunkalloc (size_t Size, int& NOBJS); User calls request memory function static void* Allocate (size_t N); Memory deallocation function static void Deallocate (Void*p, size_t N); Reallocate memory static void* reallocate (void*p, size_t OLD_SZ, size_t NEW_SZ);};/ /Initialize global static object//1. Free list Template<bool threads, int inst>typename __defaultalloctemplate<threads, inst>::obj* Volatile__defaultalloctemplate<threads, Inst>::_freelist[__defaultalloctemplate<threads, inst>::__ NFREELISTS];//2. Memory pool Template<bool threads, int inst>char* __defaultalloctemplate<threads, inst>::_ Startfree = 0;template<bool threads, int inst>char* __defaultalloctemplate<threads, inst>::_endfree = 0; Template<bool threads, int inst>char* __defaultalloctemplate<threads, inst>::_heapsize = 0;// The definition of the declared function in a class Template<bool threads, int inst>void* __defaultalloctemplate<threads, Inst>::refill (size_t N) { int nobjs = 20; char* result = Chunkalloc (n, NOBJS); if (Nobjs = = 1) return result; obj* cur = (obj*) (result + N); size_t index = Freelist_index (n); _freelist[index] = cur; for (int i = 2; i < NOBJS; ++i)//list header {Cur->_freelistlink = i*n + result; Cur = cur->_freelistlink; } Cur->_freelistlink = NULL; return result;} Template<bool threads, int inst>char* __defaultalloctemplate<threads, inst>::chunkalloc (size_t size, int &NOBJS) {char* result; size_t bytesneed = SIZE*NOBJS; size_t byteshave = _endfree-_startfree; if (byteshave >= bytesneed)//memory pool remaining memory is greater than required memory {result = _startfree; _startfree + = Bytesneed; } else if (byteshave >= size)//can satisfy at least one size allocation {result = _startfree; NOBJS = byteshave/size; _startfree + = SIZE*NOBJS; } else//memory pool is not enough space left a size {//empty memory pool, ready to add space to the memory pool obj* cur = _startfree; size_t index = Freelist_index (Byteshave); Cur->_freelistlink = _freelist[index]; _freelist[index] = cur; _startfree = null, _endfree = NULL; Re-apply to system bytesneed*2 + _heapsize/16 size_t bytestoget = bytesneed * 2 + (_heapsize >> 4); _startfree = (char*) malloc (bytestoget); if (_startfree = = NULL)//Request memory failure to the system {//First look for a for in the large memory chain upstream of the free list (int i = size; I <= __ma X_bytes; i + = __align) {obj* head = _freelist[freelist_index (size)]; if (head) {_startfree = (char*) head; _endfree = (char*) head + i; _freelist[freelist_index (size)] = head->_freelistlink; Return Chunkalloc (size, NOBJS); }}//list also No, really helpless, invoke the memory allocation function in the first-level configurator _startfree = (char*) mallocalloc::allocate (bytetoget); } _heapsize + = Bytestoget; _endfree = _startfree + bytestoget; Return Chunkalloc (size, NOBJS); Reuse of Function} return result; template<BOOL threads, int inst>void* __defaultalloctemplate<threads, inst>::allocate (size_t N) {void* result; if (n > __max_bytes) result = Mallocalloc::allocate (n); Free list has, just take//not, just fill through refill//size_t index = Freelist_index (n); if (_freelist[index]) {result = _freelist[index]; _freelist[index] = ((obj*) result)->_freelistlink; } else {result = refill (ROUND_UP (n)); } return result; Template<bool threads, int inst>void __defaultalloctemplate<threads, inst>::D eallocate (Void*p, size_t N) { if (n > __max_bytes) Mallocalloc::D eallocate (P); No more than __max_bytes, plug this space back into the free list else {size_t index = Freelist_index (n); obj* cur = (obj*) p; Cur->_freelistlink = _freelist[index]; _freelist[index] = cur; }}template<bool threads, int inst>void* __defaultalloctemplate<threads, inst>::reallocate (void* p, size_t OLD_SZ, size_t NEW_SZ) {void* Result if (Old_sz > (size_t) __max_bytes && NEW_SZ > (size_t) __max_bytes)//Return ReAlloc (P, OLD_SZ, new _SZ); if (round_up (OLD_SZ) = = Round_up (NEW_SZ)) return p; result = Allocate (NEW_SZ); size_t size = OLD_SZ > NEW_SZ? OLD_SZ:NEW_SZ; meycpy (result, p, size); Deallocate (P, OLD_SZ); return result;} typedef __defaultalloctemplate<false, 0> Alloc; #endif//__use_malloc
Two-level space Configurator
Disadvantages of STL Space Configurator:
1. Problems with internal debris
2. Memory in the memory pool can not be returned to the operating system before the end of the program, the memory is divided into small chunks are hanging under the free list, it will make the memory consumption rate is too high.
Solution:
① in the memory pool of the two-level space Configurator set a maximum allocated memory, that is, when _heapsize reached a certain value, the program will automatically throw an exception, to remind the user two-level space Configurator consumes too much memory;
② implements a mechanism to save the first address of each malloc out of space, and to record the open space in the free list (which has been divided into small pieces) of the hanging position. When it is found that the space is divided into small pieces are all hanging in the free-link table, the description can be freed up space, and now each small pieces from the free link list to remove, so that the space after the lost;
Learn ing, if you find that there is no place to write wrong, please advise ~ ~
STL Space Configurator (allocator)