slabs 内存分配原理
来源:互联网 发布:大数据可视化技术综述 编辑:程序博客网 时间:2024/05/01 17:15
前段时间,看过slabs内存分配的代码。
代码看过容易忘记,把看的用图记下来,方便后面自己看。
具体实现可以阅读代码:http://code.google.com/p/squirrel-message-queue/
或者 http://code.google.com/p/memcached/
slabs.c
#define POWER_SMALLEST 3#define POWER_LARGEST 20#define POWER_BLOCK 1048576/* powers-of-2 allocation structures */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 */} slabclass_t;static slabclass_t slabclass[POWER_LARGEST+1];static unsigned int mem_limit = 0;static unsigned int mem_malloced = 0;unsigned int slabs_clsid(unsigned int size) { int res = 1; if(size==0) return 0; size--; while(size >>= 1) res++; if (res < POWER_SMALLEST) res = POWER_SMALLEST; if (res > POWER_LARGEST) res = 0; return res;}void slabs_init(unsigned int limit) { int i; int size=1; mem_limit = limit; for(i=0; i<=POWER_LARGEST; i++, size*=2) { slabclass[i].size = size; slabclass[i].perslab = POWER_BLOCK / size; slabclass[i].slots = 0; slabclass[i].sl_curr = slabclass[i].sl_total = slabclass[i].slabs = 0; slabclass[i].end_page_ptr = 0; slabclass[i].end_page_free = 0; slabclass[i].slab_list = 0; slabclass[i].list_size = 0; slabclass[i].killing = 0; }}static int grow_slab_list (unsigned int id) { slabclass_t *p = &slabclass[id]; if (p->slabs == p->list_size) { unsigned int new_size = p->list_size ? 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;}int slabs_newslab(unsigned int id) { slabclass_t *p = &slabclass[id]; int num = p->perslab; int len = POWER_BLOCK; char *ptr; if (mem_limit && mem_malloced + len > mem_limit) return 0; if (! grow_slab_list(id)) return 0; ptr = malloc(len); if (ptr == 0) return 0; memset(ptr, 0, len); p->end_page_ptr = ptr; p->end_page_free = num; p->slab_list[p->slabs++] = ptr; mem_malloced += len; return 1;}void *slabs_alloc(unsigned int size) { slabclass_t *p; unsigned char id = slabs_clsid(size); if (id < POWER_SMALLEST || id > POWER_LARGEST) return 0; p = &slabclass[id];#ifdef USE_SYSTEM_MALLOC if (mem_limit && mem_malloced + size > mem_limit) return 0; mem_malloced += size; return malloc(size);#endif /* fail unless we have space at the end of a recently allocated page, we have something on our freelist, or we could allocate a new page */ if (! (p->end_page_ptr || p->sl_curr || slabs_newslab(id))) return 0; /* return off our freelist, if we have one */ if (p->sl_curr) return p->slots[--p->sl_curr]; /* if we recently allocated a whole page, return from that */ if (p->end_page_ptr) { void *ptr = p->end_page_ptr; if (--p->end_page_free) { p->end_page_ptr += p->size; } else { p->end_page_ptr = 0; } return ptr; } return 0; /* shouldn't ever get here */}void slabs_free(void *ptr, unsigned int size) { unsigned char id = slabs_clsid(size); slabclass_t *p; if (id < POWER_SMALLEST || id > POWER_LARGEST) return; p = &slabclass[id];#ifdef USE_SYSTEM_MALLOC mem_malloced -= size; free(ptr); return;#endif if (p->sl_curr == p->sl_total) { /* need more space on the free list */ int new_size = p->sl_total ? p->sl_total*2 : 16; /* 16 is arbitrary */ void **new_slots = realloc(p->slots, new_size*sizeof(void *)); if (new_slots == 0) return; p->slots = new_slots; p->sl_total = new_size; } p->slots[p->sl_curr++] = ptr; return;}char* slabs_stats(int *buflen) { int i, total; char *buf = (char*) malloc(8192); char *bufcurr = buf; *buflen = 0; if (!buf) return 0; total = 0; for(i = POWER_SMALLEST; i <= POWER_LARGEST; i++) { slabclass_t *p = &slabclass[i]; if (p->slabs) { unsigned int perslab, slabs; slabs = p->slabs; perslab = p->perslab; bufcurr += sprintf(bufcurr, "STAT %d:chunk_size %u\r\n", i, p->size); bufcurr += sprintf(bufcurr, "STAT %d:chunks_per_page %u\r\n", i, perslab); bufcurr += sprintf(bufcurr, "STAT %d:total_pages %u\r\n", i, slabs); bufcurr += sprintf(bufcurr, "STAT %d:total_chunks %u\r\n", i, slabs*perslab); bufcurr += sprintf(bufcurr, "STAT %d:used_chunks %u\r\n", i, slabs*perslab - p->sl_curr); bufcurr += sprintf(bufcurr, "STAT %d:free_chunks %u\r\n", i, p->sl_curr); bufcurr += sprintf(bufcurr, "STAT %d:free_chunks_end %u\r\n", i, p->end_page_free); total++; } } bufcurr += sprintf(bufcurr, "STAT active_slabs %d\r\nSTAT total_malloced %u", total, mem_malloced); *buflen = bufcurr - buf; return buf;}
- slabs 内存分配原理
- memcached内存管理(1) ----------------slabs
- 内存分配原理
- java内存分配原理
- Java内存分配原理
- Java内存分配原理
- Java内存分配原理
- Java内存分配原理
- java 内存分配原理
- Java内存分配原理
- 内存分配的原理
- Java内存分配原理
- Java内存分配原理
- Java内存分配原理
- Java内存分配原理
- java内存分配原理
- Java内存分配原理
- malloc内存分配原理
- live555简介
- Stc89c52存储空间大小问题
- LAMP开发环境搭建
- 二分查找算法整理
- Pig学习总结
- slabs 内存分配原理
- 自己动手修改宇宙无敌之Slickedit的文件切换标签栏
- UVA 10673 Play with Floor and Ceil
- node.js第一步
- 出想“java.lang.IllegalStateException: Cannot forward after response has been committed”错误
- 各种SQL在PIG中实现
- Unity3d 2种重要方法的使用
- hdu 1075
- 走进C++程序世界------多重继承