STL Source Analysis Study notes-2nd Space Configurator

Source: Internet
Author: User
Tags memory usage
1. SGI Special Space Configurator, Std::alloc

SGI STL's configurator differs from the standard specification by its name alloc rather than allocator, and does not accept any parameters.

We are accustomed to the C + + memory configuration operation and release operations as follows:

Class Foo {...};
foo* pf = new Foo; Configure the memory, then construct the object
Delete pf;//Refactor the object and then free the memory

This new operator (new operator) contains two-phase operations:

(1) Call the operator new configuration Memory
(2) to call the Foo::foo () constructor to construct the object contents.

The delete operator contains two-phase operations:

(1) Call the Foo::~foo () destructor to refactor the object.
(2) Call operator delete to free memory

Note: If you are only doing space allocation operations, then using operator new is OK, just like the malloc function of C; If you have allocated space and want to construct an object above, you can use placement new.

The STL allocator distinguishes these two-phase operations. The memory configuration operation is handled by Alloc::allocate (), which is responsible for the memory release operation by Alloc::d eallocate (); The object construction operation is performed by:: Construct (), and the object destructor is handled by::d Estroy ().

Configuration/release of memory space and construction/destruction of object content, landed on the two files of <stl_alloc.h> and <stl_construct.h> respectively. There is also a file <stl_uninitialized.h>, which defines a number of global functions that are used to populate (fill) or copy large chunks of memory data, which are also subordinate to the STL standard specification.

Summary:

STL Space Configurator consists of three file implementations:
(1) <stl_construct.h>: This defines the global function construct () and Destroy (), which is responsible for the construction and destruction of the object.

(2) <stl_alloc.h>: One, 22 level configurator is defined in the file, cooperating with each other, and the Configurator is named Alloc.

(3) <stl_uninitialized.h>: This defines a number of global functions that are used to populate (fill) or copy large chunks of memory data, and they are also subordinate to the STL standard specification.

The STL provides five global functions for processing space, respectively:

1. Construct for construction,
2. Destroy for Destruction,
3. Uninitialized_copy (First, last, result) will [First,last]
The objects within the range are copied to the result;
4. Uninitiated_fill (First, last, X) fills the first,last in the scope of [the]
object with a copy of the objects X;
5. Uninitiated_ Fill_n (First, N, X) fills n contiguous memory space beginning with first
with a copy of X;
2, Std::alloc How to eliminate the allocator in front of the high efficiency

To put it simply, Alloc has surpassed allocator in the following areas

1. Increased allocation efficiency through memory pool technology:
2. Handling of memory fragmentation issues that may result from the frequent allocation of small memory
3. Processing when the internal storage is insufficient
3, two-level space Configurator

SGI STL defines a level two configurator in <stl_alloc.h>. The first-level space Configurator uses the Malloc/free function to use the first-level space Configurator when allocating more space than bytes, and the second-level space Configurator uses the memory pool technology, which uses a second-level space Configurator when the allocated space is much smaller than the bytes.

When a user applies for a large chunk, it is handed over to the first level configurator. When the user requests the cell block, will deal with the memory pool, the memory pool through the free list (free-list) to manage the cell block , when the memory pool is insufficient, one time to the heap to apply for enough space. You can use macros to control which level of Configurator is used (the default is Level two Configurator).

Static void* Allocate (size_t __n)
  {
    void* __ret = 0;
    If greater than bytes, use the first-level space Configurator if
    (__n > (size_t) _max_bytes) {
      __ret = malloc_alloc::allocate (__n);
    }
    else {//
      free-list array subscript is obtained by size, then pointer to corresponding node
      //equivalent to &_s_free_list[_s_freelist_index (__n)]
      _obj* __stl_ volatile* __my_free_list
          = _s_free_list + _s_freelist_index (__n);
      _obj* __restrict __result = *__my_free_list;
      If no nodes are available, the new node is allocated via _s_refill if
      (__result = = 0)
        __ret = _s_refill (_s_round_up (__n));
      else {
        //removes the current node and returns it as a result to the user using
        *__my_free_list = __result, _m_free_list_link;
        __ret = __result;
      }
    }

    return __ret;
  };

allocating small chunks of memory space can be problematic : first, the memory obtained from the runtime's heap manager (as obtained through malloc) will have a portion of the space used to store management information to manage each block of memory, resulting in lower memory usage The second is the memory fragmentation problem caused by too much small chunks of memory, and the use of appropriate memory pool technology can avoid these problems .

The Configurator is also responsible for recycling in addition to being responsible for configuration. For ease of management, the SGI second level configurator proactively increases the memory requirements of any small chunk to a multiple of 8. and maintenance of 16 free-lists, respectively, the size of the management of 8,16,24,32,40,48,56,64,72,80,88,96,104, 112,120,128 bytes of small chunks. The corresponding free list is checked when the request is less than or equal to 128 bytes, and if there are chunks available in the free-list, take them directly, and if not, prepare to refill the space with refill for the corresponding free-list. The node structure of the free-list is as follows:

Union obj
{
    Union obj* free_list_link;
    Char client_data[1];
};

The union structure is used here to save space.
The recycling of the space is to re-add the memory to the free-list corresponding node linked list up. 4, the mechanism of refill

As mentioned earlier, if no chunks are available in the free-list, the space is re-populated by refill for the corresponding free-list. What kind of operation did refill do at this time?

The default action is to add 20 new nodes from the memory pool to the Free-list list by _s_chunk_alloc, and if memory in the memory pool is not enough, how many nodes can be divided, and the corresponding number of nodes returned. In case the memory pool one node is not available, give the memory pool new space, if failed, and then throw Bad_alloc exception.

Template <bool __threads, int __inst> void* __default_alloc_template<__threads, __inst>::_s_refill (size_t
    __n) {int __nobjs = 20;
    Memory is allocated through the memory pool, the second parameter is a char* __chunk = _s_chunk_alloc (__n, __NOBJS);
    _obj* __stl_volatile* __my_free_list;
    _obj* __result;
    _obj* __current_obj;
    _obj* __next_obj;
    int __i;
    If only one node is assigned, then the direct return to the user is the IF (1 = = __nobjs) return (__chunk);

    If more than one node is allocated, then we need to put the extra free-list inside to __my_free_list = _s_free_list + _s_freelist_index (__n);
      /* Build free list in chunk */__result = (_obj*) __chunk;
      *__my_free_list = __next_obj = (_obj*) (__chunk + __n);
        for (__i = 1;; __i++) {__current_obj = __next_obj;
        __next_obj = (_obj*) ((char*) __next_obj + __n); if (__nobjs-1 = = __i) {///Last node's _m_free_list_link pointer points to null and jumps out of loop __current_obj, _m_free_li
            St_link = 0;
        Break } else {__current_obj-_m_free_list_link = __next_obj;
}} return (__result); }
5. Memory Pool

With _s_chunk_alloc, allocate space from the memory pool to free-list. The _s_chunk_alloc process is summarized as follows:

1, the memory pool has enough space, the allocation of space for the application,
2, the memory pool does not have enough space, but at least can allocate a node's space, then how many points,
3, the memory Pool A node can not be released, to the system heap request twice times the required size of space, in
between this, if the memory pool remaining space, then put into the Free-list,
4, if the application of space to the heap failed, then can only see the larger node in the Free-list have available
space, there is the use of it, at the same time recursive call itself correction __ NOBJS;
5, if the free-list also has no available nodes, then to the first level Space Configurator application space; 6. No
, the first-level space Configurator throws a Bad_alloc exception.

If there is a need, the memory pool will continue to request new memory through malloc, the last memory pool will have more memory, of course, when the end of the process, the memory will be recovered by the operating system.

Section references from http://www.programlife.net/stl-allocator.html

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.