Memcache (c) Memory management

Source: Internet
Author: User
Tags cas prev

Memcached (c) Memory management

Memcached uses a pre-application approach to manage the allocation of memory to avoid memory fragmentation issues. If you use Mallo and free to dynamically request and destroy memory, you will inevitably incur a lot of memory fragmentation.

Basic knowledge

Slab: The memory block is the smallest unit that memcached request memory once, in memcached the default size of a slab is 1M;

Slabclass: A group of chunk of a specific size.

Chunk: Cached memory space, a slab is divided into a number of chunk;

Item: The smallest unit that stores data, and each chunk contains a single item;

Factor: Growth factor, default is 1.25, the item size in adjacent slab is proportional to factor;

Basic principle

Memcached uses the pre-allocation method to avoid frequent calls to malloc and free;

Memcached uses different slab to manage memory blocks of different chunk sizes, thus satisfying the storage of data of different sizes.

Slab's application is done by applying for slab size memory space when using item, and then cutting the memory to the same size item, hanging on the unused list on the slab.

Expired and deleted item will not be free, memcached will not delete the allocated memory;

Memcached will take precedence over the time-out record space, via the LRU algorithm;

Memcached uses lazy expiration to determine whether an element is out of date, so it does not consume CPU time on expired monitoring.

SOURCE Analysis

The following main analysis memcached memory request and store related code.

Item

Item is a storage unit for Key/value.

typedefstruct_stritem {struct_stritem *Next; / * Front and rear pointers for connecting before and after data in linked list Slab->slots *  /struct_stritem *prev; struct_stritem *h_next;/*Hash Chain Next*/rel_time_t time; /*Last access Time*/rel_time_t Exptime; /*Expiry Time*/    intNbytes;/*Data Size*/unsigned ShortRefCount;    / * Number of citations * /uint8_t nsuffix; /*suffix length*/uint8_t it_flags; /*item_* above*/uint8_t Slabs_clsid;/*ID of all slab*/uint8_t Nkey; /*Key Length*/    /*This odd type prevents type-punning issues if we do * the little shuffle to save space is not using CAS. */Union {uint64_t CAs; Charend; } data[]; / * Cas|key|suffix|value * /} item;
Slab initialization
voidSlabs_init (Constsize_t limit,Const DoubleFactorConst BOOLPrealloc) {    inti = power_smallest-1; unsignedintSize =sizeof(item) + Settings.chunk_size;/*get the size of each item*/Mem_limit=limit; if(Prealloc) {/*pre-allocating a piece of memory*/        ...    } memset (Slabclass,0,sizeof(Slabclass));/*set Slabclass to 0,slabclass is an slab array that stores all slab information*/     while(++i < power_largest && size <= settings.item_size_max/factor) {/*loop initializes each slab content to ensure that the size of item in slab is less than max_size/factor*/        /*Make sure items is always n-byte aligned*/        if(Size% chunk_align_bytes)/*used for memory alignment*/size+ = chunk_align_bytes-(size%chunk_align_bytes); Slabclass[i].size= size;/*Initialize the size of item in Slabclass*/Slabclass[i].perslab= Settings.item_size_max/slabclass[i].size;/*Initialize the number of item in each slab*/size*= factor;/*item size increases as factor grows*/...}/ * Initializes the last slab, size is the largest max_size, only one item * /Power_largest=i; Slabclass[power_largest].size=Settings.item_size_max; Slabclass[power_largest].perslab=1; ...}

From the source, you can see that the same slab all the item size is fixed,

Request Slab Memory
Static void*do_slabs_alloc (Constsize_t size, unsignedintID) {slabclass_t*p; void*ret =NULL; Item*it =NULL; if(ID < power_smallest | | ID > power_largest) {/*Determine if ID is legal*/memcached_slabs_allocate_failed (Size,0); returnNULL; } P= &slabclass[id];/*Get Slab*/assert (P->sl_curr = =0|| (item *) p->slots)->slabs_clsid = =0); /*fail unless we have space at the end of a recently allocated page and we have something on our freelist, or we cou LD allocate a new page*/    if(! (P->sl_curr! =0|| Do_slabs_newslab (ID)! =0)) {/*if Sl_curr is 0 and there is no remaining item, then execute DO_SLABS_NEWSLAB request memory space*/        /*We don ' t have more memory available*/ret=NULL; } Else if(P->sl_curr! =0) {/*If there is unused space, get the item and remove the item from the slots linked list*/        /*return off our freelist*/it= (item *) p->slots; P->slots = it->Next; if(it->next) It->next->prev =0; P->sl_curr--; RET= (void*) it; }    ...    returnret;}

Sl_curr to determine if there is an unused content space, and if there is no need to call Do_slabs_newslab to request slab space.

Static intDo_slabs_newslab (ConstUnsignedintID) {slabclass_t*p = &Slabclass[id]; intLen = settings.slab_reassign?settings.item_size_max:p->size * p->Perslab; Char*ptr; /*1. Determine if the memory limit is exceeded 2. Determine if you have applied for memory space 3. If you have not applied, then apply for the Slab->size*slab->perslab size of the whole block of memory 4. If you have applied, call GR  Ow_slab_list to enlarge slab size * /if ((mem_limit && mem_malloced + len > mem_limit && p->slabs > 0)        ||        (grow_slab_list (id) = = 0) | | (ptr = Memory_allocate ((size_t) len)) = = 0))        {memcached_slabs_slabclass_allocate_failed (ID);    return 0;    } memset (PTR, 0, (size_t) len); Split_slab_page_into_freelist (PTR, id); /* Allocate the requested memory to the slots linked list*/P->slab_list[p->slabs++] =ptr; mem_malloced+=Len;    Memcached_slabs_slabclass_allocate (ID); return 1;}

Once you have applied for space, you need to allocate the requested memory space to the unused list by using the Split_slab_page_into_freelist function.

Static voidSplit_slab_page_into_freelist (Char*ptr,ConstUnsignedintID) {slabclass_t*p = &Slabclass[id]; intx;  for(x =0; X < p->perslab; X + +) {/*Cyclic memory allocation*/Do_slabs_free (PTR,0, id); PTR+ = P->size; }}Static voidDo_slabs_free (void*ptr,Constsize_t size, unsignedintID) {slabclass_t*p; Item*it; .. p= &Slabclass[id]; /*Gets the memory pointer, hangs the item block in the slots list, increases the Sl_curr*/it= (Item *) ptr; It->it_flags |=item_slabbed; It->prev =0; It->next = p->slots; if(it->next) It->next->prev =it; P->slots =it; P->sl_curr++; P->requested-=size; return;}
Get an item of the appropriate size

In Do_item_alloc, Slabs_clsid is called to get the slab ID that is appropriate to store the current element.

UnsignedintSlabs_clsid (Constsize_t size) {    intres =power_smallest; if(Size = =0)        return 0;  while(Size > Slabclass[res].size)/*Traverse Slabclass to find the item that fits the size*/        if(res++ = = power_largest)/*won ' t fit in the biggest slab*/            return 0; returnRes;}
Advantages and Disadvantages

Memory pre-allocation avoids memory fragmentation and avoids the overhead of dynamic allocation.

Memory allocations are redundant, and when a slab cannot be divisible by the size of the chunk it owns, the remaining space on the slab tail is discarded.

Due to the allocation of memory of a specific length, it is not possible to effectively utilize all allocated memory, such as storing 100 bytes of data in a 128-byte chunk, resulting in a 28-byte waste.

Memcache (c) Memory management

Related Article

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.