文章目录
- 伙伴系统会产生内部碎片
- 快速适应算法不会产生内部碎片
-
下列算法中,每次回收分区时仅合并大小相等的空闲分区的是(A)
A. 伙伴算法B. 最佳适应算法
C. 最坏适应算法
D. 首次适应算法
- 连续分配存储管理方式管理的都是物理内存,而且是连续分配。
基于顺序搜索的动态分区分配算法
-
将系统中的空闲分区链接成一个链,然后依次搜索空闲分区链上的空闲分区,去寻找一个其大小能满足要求的分区的系统。
-
基于顺序搜索的动态分区分配算法包括:首次适应算法、循环首次适应算法、最佳适应算法、最坏适应算法
碎片概念
- 碎片:不能利用的小内存分区。
- 外部碎片:还没有被分配出去(不属于任何进程),但由于太小了无法分配给申请内存空间的新进程的内存空闲区域。
- 内部碎片:已经被分配出去(明确指出属于哪个进程)却不能被利用的内存空间。
首次适应算法(First Fit)
-
特点:空闲分区链以地址递增的次序链接。
-
分配方式:分配内存时,从链首开始顺序查找,找到大小能满足要求的第一个空闲分区分配给作业。
-
优点:优先利用内存低址部分的空闲分区,保留了高址部分的大空闲区,为以后大作业分配内存创造了条件。
-
缺点:低址部分不断被划分,会留下许多难以利用的很小的空闲分区,即碎片。并且每次查找都从低址部分开始,增加了查找的时空开销。
循环首次适应算法(NextFit)NF
- 特点:空闲分区链以地址递增的次序链接。
- 循环首次适应算法(临近适应算法),由首次适应算法演变而成。分配内存时从上次查找结束的位置开始继续查找。
- 优点:使内存空闲分区分布均匀,减少查找空闲分区的开销。
- 缺点:产生很多小分区,缺乏大的空闲分区
最佳适应算法(BestFit)BF
- 特点:空闲分区按容量递增的次序形成空闲分区链,找到第一个能满足要求且最小的空闲分区分配给作业。
缺点:产生许多难以利用的碎片。
最坏适应算法(WorstFit)WF
- 特点:空闲分区以容量递减的次序链接
- 分配方式:找到第一个能满足要求的,即最大的分区,从中分割一部分存储空间给作业。
- 优点:产生碎片的可能性最小,对中、小作业有利。算法查找效率很高,查找时,只要看第一个分区能否满足作业要求即可。
基于索引搜索的动态分区分配算法
- 为提高搜索空闲分区的速度,在大、中型系统中往往会采用基于索引搜索的动态分区分配算法,常用的有快速适应算法、伙伴系统和哈希算法。
快速适应算法(QuickFit)QF
-
快速适应算法(分类搜索法):将空闲分区根据其容量大小进行分类,对于每一类具有相同容量的所有空闲分区,单独设立一个空闲分区链表,这样系统中存在多个空闲分区链表。同时,在内存中设立一张管理索引表,其中的每一个索引表项对应了一种空闲分区类型,并记录了该类型空闲分区链表表头的指针。空闲分区的分类是根据进程常用的空间大小进行划分的。
-
搜索可分配的空闲分区时的两个步骤:
第1步:根据进程的长度,从索引表中去寻找到能容纳它的最小空闲区链表;
第2步:从链表中取下第一块进行分配即可。 -
优点:不会对任何分区产生分割,所以能保留大的分区,满足对大空间的需求,也不会产生内存碎片,查找效率高。
-
缺点:为了有效合并分区,在分区归还主存时的算法复杂,系统开销较大。此外,该算法在分配空闲分区时,是以进程为单位的,一个分区只属于一个进程,或多或少地存在一定的浪费。(典型的以空间换时间的做法)
伙伴系统(buddy system)
- 该算法规定,无论已分配分区或空闲分区,其大小均为 2 k 2^k 2k(k为整数, 1 < = k < = m 1<=k<=m 1<=k<=m)。通常 2 m 2^m 2m是整个可分配内存的大小(最大分区的大小)。系统开始运行时,整个内存区是一个大小为 2 m 2^m 2m的空闲分区。在系统运行过程中,由于不断地划分,将会形成若干个不连续的空闲分区,将这些空闲分区按分区的大小进行分类。对于具有相同大小的所有空闲分区,单独设立一个空闲分区双向链表,这样,不同大小的空闲分区形成了 k k k个空闲分区链表。
- linux采用伙伴系统解决外部碎片问题。
- 在伙伴系统中,其分配和回收的时间性能取决于查找空闲分区的位置和分割、合并空闲分区所花费的时间。
哈希算法
- 哈希算法利用哈希快速查找的优点,以及空闲分区在可利用空闲区表中的分布规律,建立哈希函数,构造一张以空闲分区大小为关键
字的哈希表,该表的每一个表项记录了一个对应的空闲分区链表表头指针。 - 当进行空闲分区分配时,根据所需空闲分区大小,通过哈希函数计算,即得到在哈希表中的位置,从中得到相应的空闲分区链表,实现最佳分配策略。
伙伴系统逻辑结构
- 假设系统中有1MB大小的内存需要动态管理,按照伙伴算法的要求:需要将这1M大小的内存进行划分。这里,我们将这1M的内存分为64K、64K、128K、256K、和512K共五个部分,如下图a所示
-
此时,如果有一个程序A想要申请一块45K大小的内存,则系统会将第一块64K的内存块分配给该程序(产生内部碎片为代价),如图b
-
然后程序B向系统申请一块68K大小的内存,系统会将128K内存分配给该程序,如图c
- 接下来,程序C要申请一块大小为35K的内存。系统将空闲的64K内存分配给该程序,如图d
- 之后程序D需要一块大小为90K的内存。当程序提出申请时,系统本该分配给程序D一块128K大小的内存,但此时内存中已经没有空闲的128K内存块了,于是根据伙伴算法的原理,系统会将256K大小的内存块平分,将其中一块分配给程序D,另一块作为空闲内存块保留,等待以后使用,如图e
- 紧接着,程序C释放了它申请的64K内存。在内存释放的同时,系统还负责检查与之相邻并且同样大小的内存是否也空闲,由于此时程序A并没有释放它的内存,所以系统只会将程序C的64K内存回收,如图f
- 然后程序A也释放掉由它申请的64K内存,系统随机发现与之相邻且大小相同的一段内存块恰好也处于空闲状态。于是,将两者合并成128K内存,如图g
- 之后程序B释放掉它的128k,系统也将这块内存与相邻的128K内存合并成256K的空闲内存,如图h
- 最后程序D也释放掉它的内存,经过三次合并后,系统得到了一块1024K的完整内存,如图i
伙伴系统练习题
-
伙伴系统中的伙伴是指任意两块大小相同、位置相邻的内存块。(❌)
-
在伙伴系统中,无论占用块或空闲块,其大小均为2的k(k为≥0的正整数)次幂。若内存容量为 2 m 2^m 2m,则空闲块大小只能是 2 1 , 2 2 , 2 3 , . . . , 2 m 2^1,2^2,2^3,...,2^m 21,22,23,...,2m。由同一大块分裂而得的两个小块互称"伙伴空间”,如内存大小为 2 10 2^{10} 210的块分裂成两个大小为 2 9 2^{9} 29的块。只有两
个“伙伴空间”才能合并成一个大空间。起始地址为p,大小为 2 k 2^k 2k的内存块,其伙伴的起始地址为:
若 p m o d 2 k + 1 = 0 ,则 b u d d y ( p , k ) = p + 2 k 若 p m o d 2 k + 1 = 2 k ,则 b u d d y ( p , k ) = p − 2 k 若p \bmod 2^{k+1}=0 ,则 buddy(p,k)=p+2^k \\ 若p \bmod 2^{k+1}=2^{k} ,则 buddy(p,k)=p-2^k 若pmod2k+1=0,则buddy(p,k)=p+2k若pmod2k+1=2k,则buddy(p,k)=p−2k -
二进制起始地址为 ( 011011110000 ) 2 (011011110000)_2 (011011110000)2,大小为 ( 4 ) 1 0 (4)_10 (4)10和 ( 16 ) 10 (16)_{10} (16)10块的伙伴地址分别为( 6 F 4 H 6F4H 6F4H)、( 6 E 0 H 6E0H 6E0H)
- 计算方法:直接将二进制起始地址与块大小进行异或计算即可
//大小块为4的计算 0110 1111 0000 xor 0000 0000 0100 ------------------------- 0110 1111 0100 =6F4H //大小块为16的计算 0110 1111 0000 xor 0000 0001 0000 ------------------------- 0110 1110 0000 =6E0H
-
始地址为480,大小为8的块,其伙伴块的起始地址是(488);若块大小为32,则其伙伴块的起始地址为(448)
- 方法一:二进制异或计算
//大小块为8的计算 1111 00000 =480 xor 0000 01000 =8 ------------------------- 1111 01000 =488 //大小块为32的计算 1111 00000 =480 xor 0001 00000 =32 ------------------------- 1110 00000 =448
- 方法二:假设伙伴块为该块的左边或者右边,然后计算伙伴块的起始地址是否可以整除块的二倍,可以整除,计算正确。
- 大小为8的块,其伙伴块的起始地址
- 假设伙伴块在左边,起始地址为480-8=472,472 %(8 x 2)!=0
- 假设伙伴块在右边,起始地址为480,480 %(8 x 2)=0 ,所以大小为8的块,其伙伴块的起始地址480+8=488
- 大小为32的块,其伙伴块的起始地址
- 假设伙伴块在左边,起始地址为480-32=448,448 %(32 x 2)=0
- 假设伙伴块在右边,起始地址为480,480 %(8 x 2)!=0 ,所以大小为32的块,其伙伴块的起始地址480-32=448
-
已知一个大小为512个字长的存储,假设先后有6个用户申请大小分别为23,45,52,100,11和19的存储空间,然后再顺序释放大小为45,52,11的占用块。假设以伙伴系统实现动态存储管理。
- 出可利用空间表的初始状态
- 画出为6个用户分配所需要的存储空间后可利用空间表的状态以及每个用户所得到的存储块的起始地址。
- 出可利用空间表的初始状态
3. 画出在回收3个占用块之后可利用空间表的状态