我们在前面的章节中已经详细介绍了堆在进程中的地址空间是如何分布的,对于程序来说,堆空间只是程序向操作系统申请划出来的一大块地址空间。而程序在通过 malloc申请
内存空间时的大小却是不一定的,从数个字到数个GB都是有可能的。于是我们必须将堆空间管理起来,将它分块地按照用户需求出售给最终的程序,并且还可以按照一定的方式收回内存。其实这个问题可以归结为:如何管理一大块连续的内存空间,能够按照需求分配、释放其中的空间,这就是堆分配的算法。堆的分配算法有很多种,有很简单的(比如这里要介绍的几种方法),也有些很复杂、适用于某些高性能或者有其他特殊要求的场合.
1. 空闲链表
空闲链表( Free List)的方法实际上就是把堆中各个空闲的块按照链表的方式连接起来,当用户请求一块空间时,可以遍历整个列表,直到找到合适大小的块并且将它拆分;当用户释放空间时将它合并到空闲链表中。
我们首先需要一个数据结构来登记堆空间里所有的空闲空间,这样才能知道程序请求空间的时候该分配给它哪一块内存。这样的结构有很多种,这里介绍最简单的一种空闲链表空闲链表是这样一种结构,在堆里的每一个空闲空间的开头(或结尾)有一个头( header),头结构里记录了上一个(prev)和下一个(next)空闲块的地址,也就是说,所有的空闲块形成了一个链表。如图10-15所示
在这样结构下如何分配空间呢?
首先在空闲链表中查找足够容纳大小的一个空闲块,然后将这个块分为两个部分,一部分为程序请求的空间,另一部分为剩余的空闲空间。下面将链表里对应的原来的空闲块的结构更新为新的剩下来的空闲块,如果