Memcached内存管理机制浅析

 
 

Han 通过 Google 阅读器发送给您的内容:

 
 

于 11-9-8 通过 basic coder 作者:levin

Memcached的内存管理在网上也可以搜集到不少不错的文章,新浪的这篇《Memcached深度分析》讲得不错,读别人的文章还是不如自己直接去读源码分析源码来得直接,这里写一下我阅读Memcached源码时对于Memcached内存管理机制的理解。

Memcached的代码结构很简单,从main()函数入口进去之后便是几个模块的初始化函数,和内存管理相关的主要有两个函数,一个是assoc_init(),这个是用来初始化哈希表的,关于这个哈希表的作用留在外面讨论,另一个是slabs_init(),该函数用来初始化slab,下面先来讨论一下slab机制。

1. 内存slab的管理
1.1 slabs的初始化

Memcached把内存分为一个个的slab,每个slab又分成一个个的chunk,系统会定义一个slab_class数组,其中每个元素是都是一个对该slab的描述,包括这个slab里面的每个chunk的大小,这个slab里面包含多少个chunk等信息,先把slab分布情况打印出来看看,对Memcached的内存分配有个大体的认识,然后再去读代码可能会好一些。

$ memcached -vv
slab class 1: chunk size 80 perslab 13107
slab class 2: chunk size 104 perslab 10082
slab class 3: chunk size 136 perslab 7710
slab class 4: chunk size 176 perslab 5957
slab class 5: chunk size 224 perslab 4681
slab class 6: chunk size 280 perslab 3744
slab class 7: chunk size 352 perslab 2978
slab class 8: chunk size 440 perslab 2383
slab class 9: chunk size 552 perslab 1899
slab class 10: chunk size 696 perslab 1506
slab class 11: chunk size 872 perslab 1202
slab class 12: chunk size 1096 perslab 956
slab class 13: chunk size 1376 perslab 762
slab class 14: chunk size 1720 perslab 609
slab class 15: chunk size 2152 perslab 487
slab class 16: chunk size 2696 perslab 388
slab class 17: chunk size 3376 perslab 310
slab class 18: chunk size 4224 perslab 248
slab class 19: chunk size 5280 perslab 198
slab class 20: chunk size 6600 perslab 158
slab class 21: chunk size 8256 perslab 127
slab class 22: chunk size 10320 perslab 101
slab class 23: chunk size 12904 perslab 81
slab class 24: chunk size 16136 perslab 64
slab class 25: chunk size 20176 perslab 51
slab class 26: chunk size 25224 perslab 41
slab class 27: chunk size 31536 perslab 33
slab class 28: chunk size 39424 perslab 26
slab class 29: chunk size 49280 perslab 21
slab class 30: chunk size 61600 perslab 17
slab class 31: chunk size 77000 perslab 13
slab class 32: chunk size 96256 perslab 10
slab class 33: chunk size 120320 perslab 8
slab class 34: chunk size 150400 perslab 6
slab class 35: chunk size 188000 perslab 5
slab class 36: chunk size 235000 perslab 4
slab class 37: chunk size 293752 perslab 3
slab class 38: chunk size 367192 perslab 2
slab class 39: chunk size 458992 perslab 2
slab class 40: chunk size 573744 perslab 1
slab class 41: chunk size 717184 perslab 1
slab class 42: chunk size 1048576 perslab 1

这是Memcached的默认配置,chunk size是按照CHUNK_ALIGN_BYTES对齐的,chunk size相比于前一个slab中的chunk size有一个上升因子factor,1.4.7里面factor的默认值是1.25,我们可以看到按默认配置slab总共分成了42类。
先给出一个我用Dia画的Memcached的内存分配图,Dia不如Visio好用,凑合着画了一个,如果有理解不对的地方欢迎大家指出。

接下来看一下slabs_init()的代码,还是只保留关键代码,节省版面。

void slabs_init(const size_t limit, const double factor, const bool prealloc) {     int i = POWER_SMALLEST - 1;     unsigned int size = sizeof(item) + settings.chunk_size;       mem_limit = limit;     if (prealloc) {         /* Allocate everything in a big chunk with malloc */         mem_base = malloc(mem_limit);         if (mem_base != NULL) {             mem_current = mem_base;             mem_avail = mem_limit;         }      }     memset(slabclass, 0, sizeof(slabclass));     while (++i < POWER_LARGEST && size <= settings.item_size_max / factor) {         /* Make sure items are always n-byte aligned */         if (size % CHUNK_ALIGN_BYTES)             size += CHUNK_ALIGN_BYTES - (size % CHUNK_ALIGN_BYTES);           slabclass[i].size = size;         slabclass[i].perslab = settings.item_size_max / slabclass[i].size;         size *= factor;     }     power_largest = i;     slabclass[power_largest].size = settings.item_size_max;     slabclass[power_largest].perslab = 1; #ifndef DONT_PREALLOC_SLABS     {         char *pre_alloc = getenv("T_MEMD_SLABS_ALLOC");           if (pre_alloc == NULL || atoi(pre_alloc) != 0) { 			printf("prealloc memory.\n");             slabs_preallocate(power_largest);         }     } 

评论

此博客中的热门博文

浅析Linux Kernel 哈希路由表实现(一)

通过blktrace, debugfs分析磁盘IO

ext4 bigalloc 答疑