SQlite源码分析

名词及相关概念

内存碎片:分为内部碎片和外部碎片。内部碎片是处于区域内部或页面内部的存储块。占有这些区域或页面的进程并不使用这个存储块。而在进程占有这块存储块时,系统无法利用它。直到进程释放它,或进程结束时,系统才有可能利用这个存储块。外部碎片是出于任何已分配区域或页面外部的空闲存储块。这些存储块的总和可以满足当前申请的长度要求,但由于它们的地址不连续或其他原因,使得系统无法满足当前申请。

Buddy算法:分配内存时假如系统需要4(2*2)个页面大小的内存块,该算法就到FreeList[2]中查找,如果链表中有空闲块,就直接从中摘下并分配出去。

如果没有,算法将顺着数组向上查找FreeList[3],如果FreeList[3]中有空闲块,则将其从链表中摘下,分成等大小的两部分,前四个页面作为一个块插入FreeList[2],后4个页面分配出去,FreeList[3]中也没有,就再向上查找,如果FreeList[4]中有,就将这16(222*2)个页面等分成两份,前一半挂如FreeList[3]的链表头部,后一半的8个页等分成两等分,前一半挂FreeList[2]的链表中,后一半分配出去。

假如FreeList[4]也没有,则重复上面的过程,知道到达FreeList数组的最后,如果还没有则放弃分配。内存的释放是分配的逆过程,也可以看作是伙伴的合并过程。当释放一个块时,先在其对应的链表中考查是否有伙伴存在,如果没有伙伴块,就直接把要释放的块挂入链表头;如果有,则从链表中摘下伙伴,合并成一个大块,然后继续考察合并后的块在更大一级链表中是否有伙伴存在,直到不能合并或者已经合并到了最大的块(222222222个页面)。

Robson证明:N = M*(1 + (log2 n)/2) - n + 1。N为内存分配系统为了保证不会出现分配失败而需要的原始内存数量。M为应用程序曾经在任何时间点取出的最大内存数量。N为最大内存分配与最小分配的比值。所有内存分配请求的大小都舍入到2的幂,分配从第一个满足条件的空闲内存块开始分配。此证明确保了memsys5内存分配不会出现内存碎片。