简单的内存分配算法学习
系统中一块剩余不用的大块连续内存。当需要分配内存块时,将从这个大的内存块上分割出相匹配的内存块,每个内存块都包含一个管理用的数据头,通过这个头把使用块与空闲块用双向链表的方式链接起来,如图:
mem_head是free链表的头,整个内存块从mem_x开始,每个内存块包含一个头,内容:
1、magic
魔术字,用于标记这个内存块是一个内存管理用的内存数据块;魔术字不仅仅用于标识这个数据块是一个内存管理用的内存数据块,实质也是一个内存保护字:如果这个区域被改写,那么也就意味着这块内存块被非法改写(正常情况下只有内存管理器才会去碰这块内存)
魔术字高位包括当前块是否被使用标志:used,若置位则当前块已被使用,否则是空闲块。
2、heap信息
当前堆使用信息:堆起始地址、堆的大小、堆使用大小、堆剩余大小、空闲链表头等。
3、next块
4、pre块
3和4是双向链表,链接所有的块。
5、next未使用块
6、pre未使用块
5和6也是双向链表,链接空闲链表。
头后面才是真正的内容,头信息把所有块和空闲块用双向链表链接起来,所有块是一个双向链表,空闲块也是一个双向链表,各自独立维护。
系统申请内存块时,会先从free-head指向的空闲块中查找,直到查找到满足要求,则会从此内存块中分配,若此内存块较大,则会分割出新的内存块,创建新的链表;每次分配内存块时都会留出头信息用于存放链表及堆等信息,返回的实际是头后面的内存地址。块申请后,则会将此块置位used。
系统释放内存时,会判断当前释放的块的上下块是否是空闲块,若上一个使用块是空闲块,则与上一个块合成一个块, 修改使用块链表,修改堆信息;若下一个块是空闲块,则与下一个块合成一个块,修改使用块链表,同时修改空闲块链表,修改堆信息。
释放后,将此块used位清除。