memcached 内存管理的一点变化

时间:2021-10-25 08:00:54

memcached内存管理的一些小小的变化


原来的看这里:

http://blog.developers.api.sina.com.cn/?p=124

http://basiccoder.com/memcached-memory-mamagement.html


slabs.c中原来的slabclass_t如下:

typedef struct {
    unsigned int size; /* sizes of items */
    unsigned int perslab; /* how many items per slab */
    void **slots; /* list of item ptrs */
    unsigned int sl_total; /* size of previous array */
    unsigned int sl_curr; /* first free slot */
    void *end_page_ptr; /* pointer to next free item at end of page, or 0 */
    unsigned int end_page_free; /* number of items remaining at end of last alloced page */
    unsigned int slabs; /* how many slabs were allocated for this class */
    void **slab_list; /* array of slab pointers */
    unsigned int list_size; /* size of prev array */
    unsigned int killing; /* index+1 of dying slab, or zero if none */
    size_t requested; /* The number of requested bytes */
} slabclass_t;
static slabclass_t slabclass[MAX_NUMBER_OF_SLAB_CLASSES];


而现在在官网上新下载的源码slabclass_t的结构如下:


typedef struct {
    unsigned int size;      /* sizes of items */
    unsigned int perslab;   /* how many items per slab */

    void *slots;           /* list of item ptrs */
    unsigned int sl_curr;   /* total free items in list */

    unsigned int slabs;     /* how many slabs were allocated for this class */

    void **slab_list;       /* array of slab pointers */
    unsigned int list_size; /* size of prev array */

    unsigned int killing;  /* index+1 of dying slab, or zero if none */
    size_t requested; /* The number of requested bytes */
} slabclass_t;




主要是少了end_page_ptrend_page_free2个字段。

在以前end_page_ptr是指向新分配的slab上未使用的chunk的。而现在少了这个就意味着,现在不需要这个了,因为新slab刚分配内存后就会直接通过do_slab_free放到slot中,这样就不需要区分slabslot了,可能管理起来会方便点吧。


代码如下:

static int grow_slab_list (const unsigned int id) {
    slabclass_t *p = &slabclass[id];
    if (p->slabs == p->list_size) {
        size_t new_size =  (p->list_size != 0) ? p->list_size * 2 : 16;
        void *new_list = realloc(p->slab_list, new_size * sizeof(void *));
        if (new_list == 0) return 0;
        p->list_size = new_size;
        p->slab_list = new_list;
    }
    return 1;
}

static void split_slab_page_into_freelist(char *ptr, const unsigned int id) {
    slabclass_t *p = &slabclass[id];
    int x;
    for (x = 0; x < p->perslab; x++) {
        do_slabs_free(ptr, 0, id);
        ptr += p->size;
    }
}

static int do_slabs_newslab(const unsigned int id) {
    slabclass_t *p = &slabclass[id];
    int len = settings.slab_reassign ? settings.item_size_max
        : p->size * p->perslab;
    char *ptr;

    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);

    p->slab_list[p->slabs++] = ptr;
    mem_malloced += len;
    MEMCACHED_SLABS_SLABCLASS_ALLOCATE(id);

    return 1;
}