Slab 算法的发现是基于内核中内存使用的一些特点:一些需要频繁使用的同样大小数据经常在使用后不久又再次被用到;找到合适大小的内存所消耗的时间远远大于释放内存所需要的时间。所以Slab算法的发明人认为内存对象在使用之后不是立即释放给系统而是将它们用链表之类的数据结构管理起来以备将来使用,频繁分配和释放的内存对象应该用缓存管理起来。

Slab Allocation的原理相当简单。它首先从操作系统申请一大块内存,并将其分割成各种尺寸的块Chunk,并把尺寸相同的块分成组Slab Class。

slab分配器带来的好处

通过缓存类似对象数据,内核中频繁的小数据对象的分配不会再消耗过多的时间,同时减少了系统的内存碎片

slab分配支持常用对象数据的初始化,减少了同类对象数据重复的初始化过程

slab分配支持硬件缓存对齐和着色,这样不同缓存下的对象数据可以使用同样的硬件缓存行,可以提高系统的性能

源代码实现:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#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; }

c语言slab算法,slab算法c实现相关推荐

  1. c语言算法6,c语言6函数和算法.ppt

    c语言6函数和算法创新 近半个月目标 学会使用函数进行模块化程序设计 学会调试由多个函数(包含库函数)组成的程序 主要内容 模块化程序设计思想 函数定义和函数调用.函数原型(函数声明) 函数的参数和返 ...

  2. 简单算法的举例c语言,计算机科学与技术系C语言程序设计22简单算法举例.PPT

    计算机科学与技术系C语言程序设计22简单算法举例 第2章 程序的灵魂--算法 本章主要介绍算法的思想及算法的表示方法. 2.0 绪论 2.1 算法的概念 2.2 简单算法举例 2.3 算法的特性 2. ...

  3. ML之SVM:利用Js语言设计SVM算法(SMO算法+线性核/高斯核)

    ML之SVM:利用Js语言设计SVM算法(SMO算法+线性核/高斯核) 目录 输出结果 设计思路 设计代码(部分代码) 输出结果 设计思路 设计代码(部分代码) var doTest = functi ...

  4. ML之RF:利用Js语言设计随机森林算法【DT之CART算法(gain index)】并应用随机森林算法

    ML之RF:利用Js语言设计随机森林算法[DT之CART算法(gain index)]&并应用随机森林算法 目录 输出结果 设计思路 代码实现(部分代码) 输出结果 设计思路 代码实现(部分代 ...

  5. Algorithm:C++语言实现之图论算法相关(图搜索广度优先BFS、深度优先DFS,最短路径SPF、带负权的最短路径Bellman-ford、拓扑排序)

    Algorithm:C++语言实现之图论算法相关(图搜索广度优先BFS.深度优先DFS,最短路径SPF.带负权的最短路径Bellman-ford.拓扑排序) 目录 一.图的搜索 1.BFS (Brea ...

  6. c语言大数相乘的算法_MIT 算法导论(三)

    标签:b站MIT算法导论课程的一些笔记,整理以(bu)后(hui)看 代码引用标记: 归并排序的C语言实现 第三节 分治法 分治法(Divide and conquer) 1) 分治法的步骤 把问题分 ...

  7. C语言删除链表的算法(附完整源码)

    C语言删除链表的算法 C语言删除链表的算法完整源码(定义,实现,main函数测试) C语言删除链表的算法完整源码(定义,实现,main函数测试) #include <iostream>st ...

  8. C语言merge sort归并排序算法(附完整源码)

    C语言merge sort归并排序算法 merge sort归并排序算法的完整源码(定义,实现) merge sort归并排序算法的完整源码(定义,实现) #ifndef MERGE_SORT_H # ...

  9. c语言实现stack的算法(附完整源码)

    C语言实现stack的算法 C语言实现stack的算法完整源码(定义,实现,main函数测试) C语言实现stack的算法完整源码(定义,实现,main函数测试) #ifndef STACK_H #d ...

  10. C语言flood fill 泛洪算法(附完整源码)

    C语言flood fill 泛洪算法 泛洪算法引出 C语言flood fill 泛洪算法完整源码(定义,实现,main函数测试) 泛洪算法引出 给定2D屏幕,像素的位置和要填充的颜色的新值,请用新颜色 ...

最新文章

  1. Mockito cannot mock/spy because : - final class 问题
  2. python服务端对应多个客户端_Python-网络编程:TCP2 循环为多个客户端服务
  3. python es 数据库 ik_Linux系统:centos7下搭建ElasticSearch中间件,常用接口演示
  4. 坡度土方计算案例_土石方工程造价中的细节解析(案例+计算式)
  5. 单链表的实现【数据结构】
  6. 上海事业编制 计算机 待遇怎么样,事业单位情况
  7. python消息队列模块_day43-python消息队列二-queue模块
  8. cloudflare 批量域名ID
  9. HTML5写的简单小游戏-绵羊快跑
  10. 网络时间同步系统(NTP授时服务器)在电信网络的技术性应用研究
  11. 华为路由器OSPF基础配置命令
  12. Abaqus 两套常用单位
  13. 《1024伐木累》-屌丝、快播、苍老师
  14. 四层和八层电梯控制系统Proteus仿真设计,51单片机,附仿真和Keil C代码
  15. 苹果键盘大小写键灯不亮
  16. TCPclient-Unity版本
  17. 低功耗微波雷达模块,LED庭院灯智能感应,雷达传感器助力节能减排
  18. 【xinput1_3.dll下载】xinput1_3.dll丢失怎么修复win10
  19. Elasticsearch设置ip访问
  20. Unity for Windows: II – Publishing Unity games to Windows Store

热门文章

  1. NAT和代理服务器的原理及应用
  2. 如何将企业联系方式API接口应用于你的移动端APP
  3. Diffusion相关二
  4. 如何理解Diffusion
  5. 以ear结尾的单词(ChatGPT4写作)
  6. 交通流预测——day59 交通网络动态性与多权重交通图卷积(MW-TGC)网络的交通预测
  7. Java基础——面向对象
  8. OBJECT ARX 移动,拷贝 旋转,镜像,缩放
  9. ​这些搞笑的招聘,你们是认真的吗!
  10. css零到一基础教程018:CSS 边框颜色