内存分配分为两种——固定分区分配和动态分区分配
这里讨论两种分配方式以及相应的优缺点问题
关于固定分区分配
固定分区分配:它是分区个数固定,分区的大小固定。注意只是分区大小固定并不是分区的大小一样注意区分。
分为:分区的大小一样 分区的大小不一样
一般会产生一个分区说明表例如下表所示:
分区号 | 大小(KB) | 起址(K) | 状态 |
1 | 12 | 20 | 已分配 |
2 | 32 | 32 | 已分配 |
3 | 64 | 64 | 未分配 |
4 | 128 | 128 | 已分配 |
在分配内存的时候会将用户的程序根据大小在表中找到相对应的位置装入其中并将表中状态改成已分配。
固定分区的优点:它是最早出现的分区方法这个方法思路以及实现很简单,很容易实现。
固定分区的缺点:由于它的大小是固定的所以必然出现空间的浪费会产生很多内碎片。
关于动态分区分配:
动态分区分配又称为可变分区分配。从名字中就可以看出来,它和固定分区分配所不同的就是它在分配内存分区的时候是动态的。
它会产生一个空闲分区表区别于固定分区分配的分区说明表。如下表所示:
分区号 | 分区大小(KB) | 分区始址(K) | 状态 |
1 | 50 | 85 | 空闲 |
2 | 32 | 155 | 空闲 |
3 | 70 | 275 | 空闲 |
4 | …… | …… | …… |
动态分区分配的分配算法
动态分区区别与固定分区那么它进行分配的时候就不能单独的进行寻找大小找到大小接近的分区那么简单了。这里提出三种顺序搜索的算法:
1.首次适应算法(first fit,FF)
从首地址开始顺序查找,直到找到一个大小能满足要求的空闲分区为止。
该算法的优势:
1.就是优先利用了内存中低地址的部分的空闲分区,从而保留了高地址部分的大空闲。
但是它的缺点也很明显:
1.低地址部分被不断划分,导致留下了许多的难以利用的,很小的空闲分区也就是碎片。
2.每次查找都是从低地址开始查找由于低地址都先被占用了所以只能往后面找无疑是增大了很多开销。
2.最佳适应算法(best fit,BF)
指的是每次在分配的时候总是把能满足要求的,又是最小的空闲分区分配避免大材小用。该算法要求所有的空闲分区按照从小到大的顺序排列来提高寻找的速度。直接查找到最佳的位置。
该算法的优势:
1.就是第一次能找到的空闲分区肯定是最好的最合适的,从孤立来看该算法是最佳的。
但是它的缺点也很明显:
1.首先他需要从小到大进行排序并进行查找位置所以会增加很多开销尤其是对于计算机种成千上万的空闲位置。
2.其次它虽然是找到了最佳的位置但是在划分之后产生的空闲空间必然是最小的。例如需要占用8K内存系统分配了9K孤立来看肯定是最佳的但是产生的1K的空间很大概率无法再使用所以会产生很多碎片导致浪费。
3.最坏适应算法(worst fit, WF)
这个算法和最佳适应算法是相反的,它要求系统在分配的时候提供一个最大的空间进行分配。它要求空闲分区按照从大到小的顺序进行排序。查找时候只需要看第一个是否满足分配即可。
该算法的优势:
1.使剩下的空间不会太小这样就能充分利用不至于产生较多的碎片产生浪费的问题。
2.它在分配的时候进行查找空闲分区表的时候只需要看第一个大小是否满足即可所以效率很快。
但是它的缺点也很明显:
1.由于总是把最大的分区进行划分所以到最后系统中没有大的分区导致后面的大的进程无法分配相对应大小的空间。
关于内存的回收问题:
关于内存的回收,总共可以有四种情况:
1.回收区上面的分区是空闲分区
2.回收区下面的分区是空闲分区
3.回收区上面下面的分区都是空闲分区
4.回收区上面下面的分区都不是空闲分区
每种情况的回收情况
1.回收区在空闲区下面:
使用空闲链表的数据结构来保存空闲区,不需要新建空闲链表节点、只需要将空闲区的容量增大为原来空闲区和回收区的容量之和即可(也就是将回收区包含进来)
2.回收区在空闲区上面:
将回收区与空闲区合并的容量大小为新的空闲区的容量大小,新的空闲区在空闲链表中的地址使用之前回收区的地址
3.回收区在两个空闲区中间:
将两个回收区与空闲区合并的容量大小为新的空闲区的容量大小,新的空闲区在空闲链表中的地址使用之前空闲区1的地址
4.单独的回收区:
新建一个单独的地址节点放到空闲链表当中,大小为回收区的大小。