主要是介绍一下常用的内存管理算法以及相关的数据结构.
三种类型:
1 sequential fit
包括first fit,next fit,以及best fit
这种算法的实现基本来说都是基于一个双向链表或者循环链表来保存所有的free memory.而且一般都会使用kunth的boundary tag算法来合并临近的内存(这个算法可以去网上搜索下,这里就不介绍了).
其中free block的顺序一般为FIFO,LIFO或者address order(AO).
而从free list中分配block则有三种方法. 第一种 就是 first fit,也就是从头开始搜索,找到第一个可以满足请求大小的block. 第二种是next fit,它是从最后一次搜索停止的地方开始搜索,找到下一个满足请求大小的block.
第三种是best fit,它是每次都是遍历list,然后找到满足请求大小的最小的那个block.
fist fit : 当找到的block比请求的大的话,就分割这个block将剩余的插入到free list中.我们可以看到,这样的话会使得前面的block越来越小,从而导致每次搜索都会越来越远.
next fit: 可以看做是优化版的 first fit.
best fit: 它是从生成的内存碎片来看,最好的一种策略,因为它会产生最小的碎片.可是由于它会每次遍历所有block,所以它的效率比较低.为了解决它的碎片问题,那就是每次提交给请求者的内存都会大于等于它的请求值.不过这样会导致内存浪费. 而segreganted fit算法可以看做是best fit的一种很好的补充(下面会介绍这个算法).
2 segreganted free list
这种数据结构其实也就是将相同大小的block放在一个链表,然后将将这些链表再组合成一个链表或者数组(可以看到memcached也就是用的这种算法).当请求到来时,从最合适的size大小的链表中取得一个block.而一般block的大小都是2的次幂.比如2,4,8等等.
segreganted fit算法
也就是当请求到来时,会将每次提交的值按一定的规则对齐,然后从free list搜索的话就按对齐后的这个值来搜索,一般都是先从数组或者链表中去的当前的size class然后再在这个size class中搜索可用的block(memcached也就是使用的这种内存管理算法).
3 buddy system
包括binary buddy和double buddy.
buddy system可以说是segreganted free list的一个变体.它只不过提供了一个受限制的但是高效的分割和组合内存块的算法.在一个简单的buddy结构中,整个内存堆被分为两个块,这两个块就称作一对buddy.而当内存请求到来时,它会像segreganted free list中处理的那样,先将请求大小对齐,然后再递交给buddy system.将会不断地平均切割内存,直到得到一个最小的满足请求的大小的块.而当内存块被释放时,它会尝试合并内存块,而合并内存块的话,一个内存块只能和它的buddy合并.
可以看下面的图:
binary buddy
这个是最简单的也是最流行的,所有的buddy大小都是2的次幂,然后每次分割都是将一个块分为相等的两个块.这个缺点就是容易造成内存碎片.
Fibonacci buddy
和binary buddy 类似,只不过buddy大小是按Fibonacci排列(16, 32, 48, 80, 128, 208...)
double buddy
这个它会使用两个buddy system,比如一个是按binary buddy(2,4,8,16...)而另一个则使用2的倍数并且起始数是一个不同的值(3,6,12....).当请求到来,会选择一个最合适的块.这个会很大的降低内存碎片.
通过这个解决方法我们也可以在segreganted fit中使用,也就是我们可以提供两种机制,也就是每次提供一对内存块给请求,然后选择最合适的(可以试下改进memcached).
转自stillzhang的blog