- 页:固定的
- 段:无固定,但有最大值
虚拟内存的出现有两个原因
- 希望编程的时候写出来的东西和物理空间没有任何关系
- 多个进程在同时使用内存的时候,可以让出宝贵的硬件内存空间
这个时候需要对内存进行管理:
- 虚拟地址空间:地址线支持的位数,和物理内存无关
- 将内存划分:页式内存管理、段式内存管理、页段式内存管理
- 能够确定虚拟内存地址到实际上的物理地址的映射关系:存表,表为多对一的映射,因此需要用外存保存一部分内存的数据(这里隐含的假设式外存式无限大的),和 cache 一样存在淘汰问题(唤出、唤入)。这里内存找不到的时候称为 缺页中断,load 的过程称 缺页中断处理,对系统程序员不透明。
用页管理的时候同样可以将地址分成两部分:页号和页内地址
CPU 给出的是虚拟地址,地址前面的若干位为虚页号,页内地址和实际一样,所以任务为将虚页号映射成实页号。
内存中维护一个表:虚页号 → 实页号。
- 查表,拿到实页号拼接页内地址(有效位管理、脏标记位、替换控制位)
- 访问实际物理单元取数据。
- 可能内存中没有(地址指向硬盘),产生缺页中断,拿到实际数据然后唤入
至少访问两次,如果希望能够提升内存访问速度,有硬件 TLB(快表) cache 加速
每一个进程都有自己的页表,唤起的时候会被装载进硬盘,放在哪里?
页基址寄存器:x86 是一个,其他架构有 工作面 的概念,可以非常快的切换进程
对于页是固定的,机械的切分可能会对频繁访问的区域刚好跨页了,会出现页式管理的抖动问题
因为程序可以掌握额外的局部性信息,所以可以采用段式存储
能规定语义含义,长度,起始地址
将地址分成:段号 + 段偏移量。这里因为段长度会变,只能通过起始地址 + 偏移量确定物理地址
段式管理的开销会更小
段表项数小,不用 cache(本身就是 cache)段基址寄存器
最基本长度可以是 64k,粒度大,中间会有空隙,解决这个问题有两种方式:
- 段整理:直接贴在一起,需要修改、搬运(不可行)
- 段页结合式:下面详细讲:
段页结合式
每个段还有自己的页表,操作系统可以以段为单位来管理,内存可以以页来管理(实现二级管理)
但是访问内存的次数变多了
操作系统的坑 TODO