一.概念
二.可利用空间表
- 系统运行期间所有用户请求分配的存储大小相同。
- 系统运行期间用户请求分配的存储量有若干中大小的规格。
- 系统在运行期间分配给用户的内存块的大小不固定,可以随请求而变。
三.分配方法
- 首次拟合法
- 最佳拟合发
- 最差拟合法
四.边界标识法
操作系统中用以进行动态分区分配的一种存储管理方法。系统将所有的空闲块链接在一个双重循环链表结构的可利用空间表中。
- 可利用空间表结构
- 分配算法(有待研究。。。)
- 回收算法
在用户活动完成,系统需要立即回收被用户占用的存储空间,以备新的用户使用。回收算法中需要解决的问题是:在若干次分配操作后,可利用空间块中会产生很多存储空间很小以致无法使用的空闲块。但是经过回收用户释放的空间后,可利用空间表中可能含有地址相邻的空闲块,回收算法需要将这些地址相邻的空闲块合并为大的空闲块供新的用户使用。
合并空闲块有 3 种情况(合并的原則是空闲区域向左边并):
- 该空闲块的左边有相邻的空闲块可以进行合并;
- 该空闲块的右边用相邻的空闲块可以进行合并;
- 该空闲块的左右两侧都有相邻的空闲块可以进行合并;
- 如果当前空闲块的左右两侧都不是空闲块,而是占用块,此种情况下只需要将新的空闲块按照相应的规则(头部拟合法随意插入,其它两种方法在对应位置插入)插入到可利用空间表中即可。
- 如果该空闲块的左侧相邻的块为空闲块,右侧为占用块,处理的方法是:只需要更改左侧空闲块中的 size 的大小,并重新设置左侧空闲块的 foot 域即可(如图 2)。
- 如果用户释放的内存块的相邻左侧为占用块,右侧为空闲块,处理的方法为:将用户释放掉的存储块替换掉右侧的空闲块,同时更改存储块的 size 和右侧空闲块的 uplink 指针的指向(如图 3 所示)。
4.如果当前用户释放掉的空闲块,物理位置上相邻的左右两侧的内存块全部为空闲块,需要将 3 个空闲块合并为一个更大的块,操作的过程为:更新左侧空闲块的 size 的值,同时在可利用空间表中摘除右侧空闲块,最后更新合并后的大的空闲块的 foot 域。
详情请点击这里
五.伙伴系统
操作系统中用到的另一个动态存储管理方法。和边界标识法类似。
区别是:伙伴系统中,无论是占用块还是空闲块,其大小均为2的k次幂(k为正整数)。当用户申请n个字的内存区时,分配的占用块大小为2^K 个字。(2(k-1)<=n<=2k)。
- 可利用空间表结构
伙伴系统中可利用空间表中的结点构成如图 1 所示:
- 分配算法
伙伴系统的分配算法很简单。假设用户向系统申请大小为 n 的存储空间,若 2^(k-1 )< n <= 2^k,此时就需要查看可利用空间表中大小为 2k 的链表中有没有可利用的空间结点:
如果该链表不为 NULL,可以直接采用头插法从头部取出一个结点,提供给用户使用;
如果大小为 2^k 的链表为 NULL,就需要依次查看比 2^k 大的链表,找到后从链表中删除,截取相应大小的空间给用户使用,剩余的空间,根据大小插入到相应的链表中。
例如,用户向系统申请一块大小为 7 个字的空间,而系统总的内存为 24 个字,则此时按照伙伴系统的分配算法得出:2^2 < 7 < 2^3,所以此时应查看可利用空间表中大小为 2^3 的链表中是否有空闲结点:
如果有,则从该链表中摘除一个结点,直接分配给用户使用;
如果没有,则需依次查看比 2^3 大的各个链表中是否有空闲结点。假设,在大小 2^4 的链表中有空闲块,则摘除该空闲块,分配给用户 2^3 个字的空间,剩余 2^3 个字,该剩余的空闲块添加到大小为 2^3 的链表中。
- 回收算法
无论使用什么内存管理机制,在内存回收的问题上都会面临一个共同的问题:如何把回收的内存进行有效地整合,伙伴系统也不例外。
当用户申请的内存块不再使用时,系统需要将这部分存储块回收,回收时需要判断是否可以和其它的空闲块进行合并。
在寻找合并对象时,伙伴系统和边界标识法不同,在伙伴系统中每一个存储块都有各自的“伙伴”,当用户释放存储块时只需要判断该内存块的伙伴是否为空闲块,如果是则将其合并,然后合并的新的空闲块还需要同其伙伴进行判断整合。反之直接将存储块根据大小插入到可利用空间表中即可。
判断一个存储块的伙伴的位置时,采用的方法为:如果该存储块的起始地址为 p,大小为 2^k,则其伙伴所在的起始地址为:
总结
使用伙伴系统进行存储空间的管理过程中,在用户申请空间时,由于大小不同的空闲块处于不同的链表中,所以分配完成的速度会更快,算法相对简单。
回收存储空间时,对于空闲块的合并,不是取决于该空闲块的相邻位置的块的状态;而是完全取决于其伙伴块。所以即使其相邻位置的存储块时空闲块,但是由于两者不是伙伴的关系,所以也不会合并。这也就是该系统的缺点之一:由于在合并时只考虑伙伴,所以容易产生存储的碎片。
-詳情点击这里