共计 1776 个字符,预计需要花费 5 分钟才能阅读完成。
在没有其余技术支持下,调配给一个过程的内存空间必定是间断的,如何分配内存给过程能力使得物理内存利用率更好?因为每个过程执行工夫不同,所以会有一些过程比拟早完结,也有一些过程开始得比拟晚。当给新的过程分配内存空间时,有些开释掉的内存空间比拟小,无奈利用,天然就造成了内存碎片。
1.1 内存碎片
间断内存调配是指给过程调配一块不小于指定大小的间断物理内存。如图 1 所示,一开始先给 3 个过程别离调配了间断的物理内存,其中过程 P1 占地址空间 0 -2,过程 P2 占地址空间 3 -8,过程 P3 占地址空间 9 -14。而后过程 P2 被开释掉,此时若须要调配一个内存大小为 10 的过程,则过程 2 开释掉的内存空间无奈给新过程,造成了内存碎片,能够看出所谓的内存碎片其实是相对而言的。
<center> 图 1 </center>
内存碎片分类:
- 内部碎片:已分配内存单元之间的未被应用的内存空间,例如过程 P2 所开释的内存
- 外部碎片:调配单元外部的未被应用的内存,然而取决于调配单元是否须要取整。例如调配 510 内存空间,实际上只能调配 512 这种 $2^n$ 大小的内存空间,这时候就有 2 个字节无奈利用,造成外部碎片,如图 2 所示的黄色块。
<center> 图 2</center>
1.2 间断内存调配 - 动态内存调配
间断的内存空间如何调配能力更好地进步内存利用率?依据过程指定一个大小可变的分区 (块,内存块) 称为动态内存调配,因为依据理论状况为过程找一块适合大小的内存块,大一点的过程天然也调配更大的内存块,小的过程调配小的内存块,所以就叫动态内存调配了。
当初假如有 5 个过程,占用内存状况如图 3(左)所示,过程 2 和过程 4 完结后内存占用状况如图 3(右)所示。
<center> 图 3 </center>
因为要给新过程找个适合的内存块,首先得晓得哪些内存块是闲暇的,哪些是被配置,操作系统须要保护这样的一个数据结构。那又该如何给某个过程找到一个适合的内存块使得总体内存利用率更好呢,有几种策略。别离是最先匹配法,最佳匹配法还有最差匹配法。
最先匹配法 :调配 n 个字节,应用第一个可用的比 n 大的闲暇块。举个栗子,图 4(左) 蓝色块示意为按地址排列的闲暇块,如果要分 500B 内存块给新过程,那么 1K 内存块会是第一个找到的比 500B 大的闲暇块,将其中的 500B 内存调配给新过程,新的被调配的内存块会退出被调配的列表中,并注明是哪个过程所应用,剩下的 500K 闲暇块更新到闲暇列表中去。调配后闲暇块如图 4(b)所示。
<center> 图 4 </center>
实现过程:
- 闲暇分区按地址排序
- 调配过程中,从头往后找,寻找第一个适合的内存块,更新列表
- 开释内存块时,查看是否可与邻近闲暇块合并,更新列表
长处:
- 简略
- 因为后面找到了就不再往后找了,所以高地址可能会保留着较大的内存块,不便前面更大的过程申请更大的内存块。
毛病:
- 因为会把较大内存块分成几个小块,所以会留下内部碎片
- 因为留下内部碎片,所以申请较大内存块时候会比较慢
最佳匹配 :调配 n 字节内存块时候,查找并应用大于 n 的最小内存块。举个栗子,还是如图 4(左) 所示,蓝色块示意为按地址排列的闲暇块,如果要给新过程调配 2k 字节的内存块,那么将会找到最初那个 3k 内存块,并调配 2k 被新过程,同时并更新被调配和空间内存的列表。
实现过程如下所示:
- 闲暇分区 从小到大 排序
- 调配时,查找一个适合的分区,更新列表
- 开释内存块时,查找并且合并邻近的闲暇区域(如果找到,邻近指的是地址邻近不是大小邻近,所以相比最先匹配简单一些),更新列表
长处:
- 可防止的闲暇分区被拆分
- 可缩小内部碎片大小
- 绝对简略
毛病:
- 开释内存块时较慢
- 内部碎片
- 容易产生很多无用的小碎片
最差匹配 :调配 n 字节,应用尺寸不小于 n 的最大闲暇内存块。举个栗子,还是如图 4(左) 所示,蓝色块示意为按地址排列的闲暇块,如果要给新过程调配 2k 字节的内存块,那么将会找到两头那个 10k 内存块,并调配 2k 被新过程,同时并更新被调配和空间内存的列表。
实现过程如下所示:
- 闲暇分区按 从大到小 排序
- 调配选最大内存块
- 开释内存块时,查看是否可与邻近的闲暇块去进行合并,并调整闲暇内存块列表程序
长处:
- 中等大小的内存块调配较多时,成果最好,因为剩下那内存块还能利用起来,相当于剩下的小块比拟少
- 避免出现太多的碎片
毛病:
- 开释分区较慢
- 内部碎片
- 容易毁坏大的闲暇内存块,后续难以调配大的内存块# 3. 物理内存治理 - 间断内存调配