内存分配
连续内存分配
问题
- 内部碎片:分配的空间没使用的内存。
- 外部碎片:未分配的内存。
分区的动态分配
- 第一匹配分配:碰到的第一个合适的直接分配
- 优势:
- 简单
- 容易产生较大的内存块
- 缺点:
- 容易产生外部碎片
- 不确定性
- 优势:
- 最优适配原则:将内存块按内存大小排序,选择最小的
- 优势:
- 大部分分配是小尺寸时高效
- 缺点:
- 重分配慢
- 产生很多没用的微小碎片
- 优势:
- 最差适配原则:将内存块按大小排序,选择最大的
- 优势:
- 容易产生适中尺寸的内存块
- 缺点
- 重分配慢
- 容易把大内存块分成小的导致无法继续分配
- 优势:
总结
以上三种方法没有哪个好哪个坏,因为你无法预判未来需要使用的内存是什么样的,只能说尽可能选择最合适的。
碎片整理方法
- 压缩式碎片整理
- 重置程序以合并碎片
- 如:A-空-B-C-空-D,合并完ABCD
- 交换式碎片整理
- 将没有运行的程序暂时存入硬盘中。
非连续内存
连续内存的缺点
- 物理内存都是连续的
- 利用率低
- 有碎片问题
非连续内存的好处
- 一个程序的物理地址空间是非连续的
- 更好的内存利用和管理
- 允许共享代码与数据(共享库等…)
- 支持动态加载和动态链接
缺点
- 物理内存与虚拟内存转化是个麻烦事
物理内存与虚拟内存转化有硬件方案,软件方案两种,其中软件方案消耗太大,一般采用硬件方案。
分段
根据应用程序的执行特点分类,如:头文件段,代码段等等。
通过映射,需要一个二元组(段号,地址),操作系统需要维护一个段表,维护(段号,物理内存中的地址,长度限制)
物理地址=段表的起始地址+偏移量
分页
划分物理内存至固定大小的帧
划分逻辑地址空间至相同大小的页
建立方案 → 转换逻辑地址为物理地址
操作系统维护一张页表, 页表保存了逻辑地址——物理地址之间的映射关系
- 逻辑地址空间应当大于物理内存空间
- 页映射到帧
- 页是连续的虚拟内存
- 帧是非连续的物理内存(有助于减少碎片的产生)
- 不是所有的页都有对应的帧
分段与分页区别
分段的中的段是有实际意义的,根据每一段程序执行的特点划分,分页就是相同大小,没有意义。
现如今还有一种方法是段页式管理机制,先分段,段内再分页。
页表
CPU根据程序的page的页号的若干位, 计算出索引值index, 在页表中搜索这个index, 得到的是帧号, 帧号和原本的offset组成物理地址.
特殊位(页面置换算法用到了):
- dirty bit
- resident bit, (0 : 对应的物理页帧在内存中不存在 ; 1 : 存在)
- clock / reference bit
二级页表
对于虚拟地址来说,32位的地址对应的那是4,294,967,294个虚拟地址,也就是4个G,显然是不可能的,很明显,很多虚拟地址没有对应的物理地址,那么将页表再分,对于大范围内没有与之对应的物理地址的不在用页表维护。如:0x32323212-0x40000000处没有物理地址,那么顶级页表对应这部分的直接返回空。
这样页表就能大大减小。
反向页表
二级页表依旧有虚拟地址无法对应物理地址的存在,那么直接让物理地址对应虚拟地址,这样就可以彻底解决这个问题
缺点
- 需要的信息对调了, 即根据帧号可以找到页号
- 如何转换回来? (如何根据页号找到帧号)
- 在需要在反向页表中搜索想要的页号
以上均是我自学操作系统的一点笔记,如有错误,还望批评指正。