space configurator

1. SGI standard space configurator, std::allocator

SGI defines a configurator named allocator that complies with some standards, but due to its inefficiency, its internal implementation only makes a simple encapsulation of new and delete, so it is not recommended to be used.

 

2. SGI special space configurator, std::alloc

Two-level configurator, the first-level configurator directly uses malloc and free, and the second-level configurator adopts different strategies according to the situation. First-level configurator; when the configuration block is less than 128bytes, it is regarded as a small block, and the memory pool management method is adopted. In SGI STL, both the first-level and second-level configurators are used.

 

An important flow chart is as above. According to whether __USE_MALLOC is defined, it is determined whether only the first-level configurator is used, or the first and second-level configurators coexist. Among them, simple_alloc, as a class interface, encapsulates the memory application and release of the space configurator.

 

Third, the first-level configurator, __malloc_alloc_template

The implementation of the first-level configurator mainly encapsulates system functions such as malloc, free, and realloc. Take a look at the specific implementation.

Among them, oom_xxx here is a function pointer, which corresponds to dealing with insufficient memory in different situations. The "insufficient memory processing routine" is called cyclically in the function. The "processing routine" here is set by itself. If it is not implemented, oom_xxx will throw bad_alloc exception information, or directly exit(1) to terminate the program.

 

Fourth, the second-level configurator, __default_alloc_template

The second-level configurator employs strategies to avoid memory fragmentation caused by too many too small blocks. The specific strategy is: if the block exceeds 128bytes, it will be handed over to the first-level configurator for processing. If it is less than 128bytes, it will be managed by the memory pool (each time a block of memory is configured, the corresponding free-list will be maintained. The memory requirements of the same size are directly extracted from the free-list. If the block is released, the free-list will be reclaimed by the configurator)

 

1. Implementation of the space configuration function allocate()

 

If the above is greater than 128, directly call the first-level configurator, otherwise apply for memory pool allocation. The specific schematic diagram is as follows:

1) First, according to the required size n, find the corresponding position in free_list, FREELIST_INDEX realizes memory alignment.

2) Assign the current block pointer to result

3) Extract the allocated blocks of the current free_list and return the client result

 

2. The space release function deallocate() is implemented

The code is omitted (see "STL Source Code Analysis" for details), and the specific process is:

1) If it is greater than 128, directly call the release function of the first-level configurator

2) According to the released memory size n, find the corresponding free_list

3) Reclaim blocks and adjust free_list

The schematic diagram is as follows:

 

3. Repopulate free lists

If there are no available blocks in the free_list, call refill() to refill the free list. The new space will be taken from the memory pool (completed by chunk_alloc). By default, 20 new nodes (new blocks) are obtained. The specific process is:

1) char *chunk = chunk_alloc(n, nobjs), call the allocation function, nobjs is 20, passed by reference;

2) Call free list and put a new node

 

4, chunk_alloc memory pool allocation

The specific process is:

1) Calculate the remaining memory space of the memory pool

2) If the remaining space of the memory pool fully meets the demand, modify the remaining space of the memory pool and return the required allocated memory;

3) If the remaining space in the memory pool cannot fully meet the demand, but is enough to supply more than one block, calculate the blocks that can be allocated, modify the remaining space in the memory pool, and return the memory to be allocated;

4) If the remaining space in the memory pool cannot provide even a block. Call malloc to allocate new memory to replenish the memory pool. If the operating system does not have any and cannot malloc new memory, call the first-level configurator to release the memory and try to allocate again

5) None of the above can be successfully allocated, and a bad_alloc exception is issued

The flow chart is as follows:

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325808250&siteId=291194637