Memcached内存管理slabclass

本文详细介绍了Memcached的slab内存池分配机制,包括slab简介、分配规格设定、内存预分配过程以及从内存池中申请内存的方法。通过深入理解这些内容,有助于更好地掌握Memcached的内存管理策略。
摘要由CSDN通过智能技术生成

转载请注明出处:http://blog.csdn.net/luotuo44/article/details/42737181
温馨提示:本文用到了一些可以在启动memcached设置的全局变量。关于这些全局变量的含义可以参考《memcached启动参数详解》。对于这些全局变量,处理方式就像《如何阅读memcached源代码》所说的那样直接取其默认值。

slab内存池分配

slab简介:

    memcached使用了一个叫slab的内存分配方法,有关slab的介绍可以参考链接1和链接2。可以简单地把它看作内存池。memcached内存池分配的内存块大小是固定的。虽然是固定大小,但memcached的能分配的内存大小(尺寸)也是有很多种规格的。一般来说,是满足需求的。

    memcached声明了一个slabclass_t结构体类型,并且定义了一个slabclass_t类型数组slabclass(是一个全局变量)。可以把数组的每一个元素称为一个slab分配器。一个slab分配器能分配的内存大小是固定的,不同的slab分配的内存大小是不同的。下面借一幅经典的图来说明:



    从每个slab class(slab分配器)分配出去的内存块都会用指针连接起来的(连起来才不会丢失啊)。如下图所示:




    上图是一个逻辑图。每一个item都不大,从几B到1M。如果每一个item都是地动态调用malloc申请的,势必会造成很多内存碎片。所以memcached的做法是,先申请一个比较大的一块内存,然后把这块内存划分成一个个的item,并用两个指针(prev和next)把这些item连接起来。所以实际的物理图如下所示:


    上图中,每一个slabclass_t都有一个slab数组。同一个slabclass_t的多个slab分配的内存大小是相同的,不同的slabclass_t分配的内存大小是不同的。因为每一个slab分配器能分配出去的总内存都是有一个上限的,所以对于一个slabclass_t来说,要想分配很多内存就必须有多个slab分配器。

确定slab分配器的分配规格:

    看完了图,现在来看一下memcached是怎么确定slab分配器的分配规格的。因为memcached使用了全局变量,先来看一下全局变量。

[cpp] view plain copy
在CODE上查看代码片派生到我的代码片

//slabs.c文件  
typedef struct {  
    unsigned int size;//slab分配器分配的item的大小     
    unsigned int perslab; //每一个slab分配器能分配多少个item  

    void *slots;  //指向空闲item链表  
    unsigned int sl_curr;   //空闲item的个数  

    //这个是已经分配了内存的slabs个数。list_size是这个slabs数组(slab_list)的大小    
    unsigned int slabs; //本slabclass_t可用的slab分配器个数     
    //slab数组,数组的每一个元素就是一个slab分配器,这些分配器都分配相同尺寸的内存  
    void **slab_list;     
    unsigned int list_size; //slab数组的大小, list_size >= slabs  

    //用于reassign,指明slabclass_t中的哪个块内存要被其他slabclass_t使用  
    unsigned int killing;   

    size_t requested; //本slabclass_t分配出去的字节数  
} slabclass_t;  

#define POWER_SMALLEST 1  
#define POWER_LARGEST  200  
#define CHUNK_ALIGN_BYTES 8  
#define MAX_NUMBER_OF_SLAB_CLASSES (POWER_LARGEST + 1)  


//数组元素虽然有MAX_NUMBER_OF_SLAB_CLASSES个,但实际上并不是全部都使用的。  
//实际使用的元素个数由power_largest指明  
static slabclass_t slabclass[MAX_NUMBER_OF_SLAB_CLASSES];//201  
static int power_largest;//slabclass数组中,已经使用了的元素个数.  


    可以看到,上面的代码定义了一个全局slabclass数组。这个数组就是前面那些图的slabclass_t数组。虽然slabclass数组有201个元素,但可能并不会所有元素都使用的。由全局变量power_largest指明使用了多少个元素.下面看一下slabs_init函数,该函数对这个数组进行一些初始化操作。该函数会在main函数中被调用。

[cpp] view plain copy
在CODE上查看代码片派生到我的代码片

//slabs.c文件  
static size_t mem_limit = 0;//用户设置的内存最大限制  
static size_t mem_malloced = 0;  

//如果程序要求预先分配内存,而不是到了需要的时候才
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值