1. 存储管理器
有效地管理内存,即记录哪些内存正在使用,哪些内存是空闲的,在进程需要时分配为其分配内存,在进程使用完后释放内存。
2. 几种存储管理方案
1) 无存储器抽象:每一个程序都直接访问物理内存
2) 一种存储器抽象:地址空间
3) 虚拟内存
3. 地址空间
是一个进程可用于寻址内存的一套地址集合,每个进程都有一个自己的地址空间,并且该空间独立于其他进程(除了在一些特殊情况下进程需要共享它们的地址空间外)
4. 简单的寻址解决方法:动态定位(不适用于现代CPU)
基址寄存器:起始物理地址
界限寄存器:程序长度
缺点:每次访存需进行比较和加法运算,加法很慢。
5. 交换技术
处理内存超载的方法之一,另一种是虚拟内存。
把一个完整进程调入内存,运行一段时间后,存回磁盘,空闲进程主要在磁盘上。
内存紧缩:指小的空闲区合成一大块(一般不进行,速度慢)
6. 空闲内存管理
1) 使用位图的存储管理
2) 使用链表的存储管理
7. 为创建的进程分配内存
(按地址顺序在链表中存放进程和空闲区时)
算法:
1) 首次适配算法
2) 下次适配算法
3) 最佳适配算法
4) 最差适配算法
5) 快速适配算法
8. 虚拟内存
基本思想:每个程序拥有自己的地址空间,这个地址空间被分割成多个块,每个块称为一页(page),每个页有连续的地址范围。页被映射到物理内存。这些页部分调入内存即可运行,当程序引用地址时,由硬件立刻执行必要的地址映射,如果引用到不在内存中的地址空间时,由操作系统负责将缺失的部分装入物理内存并重新执行失败的指令。
9. 内存管理单元MMU
把虚拟地址映射为物理内存地址
虚拟地址空间按照固定大小划分成称为页面的若干单元。
在物理内存中对应的单元称为页框。
会产生缺页中断是因为虚拟地址空间比物理内存大
10. 页表
用于把虚拟页面映射为页框
虚拟地址空间被分为虚拟页号和偏移量两部分
| 高速缓存禁止位 | 访问位 | 修改位 | 保护位 | “在/不在”位 | 页框号 |
11. 加速分页过程
1) TLB
将虚拟地址直接映射到物理地址,而不必再访问页表的硬件设备,转换检测缓冲区,又称相联存储器,快表。
2) 软件TLB管理
软失效:在内存中而不在TLB,更新TLB
硬失效:不在内存中也不在TLB,需一次磁盘存取
12. 针对大内存的页表
1) 多级页表
2) 倒排页表:在实际内存中每一个页框有一个表项,用散列提高虚拟页面到物理地址的映射速度
13. 页面置换算法
1) 最优页面置换算法(不可能实现)
2) 最近未使用页面置换算法(NRU)
3) 先进先出页面置换算法(FIFO)
4) 第二次机会页面置换算法(检查最老页面R位(R=0立刻置换,R=1清0放链表尾端)
5) 时钟页面置换算法(环形链表,R=0淘汰,R=1清0并表针前移)
6) 最近最少使用页面置换算法(LRU,链表,最近最多使用在表头)
老化算法(用于模拟LRU)
R位被加进之前先将计数器右移一位
R位加到计数器最左端
7) 最不常使用算法(NFU,计数器初值0,每次中断,将每个页面的R位加到计数器)
8) 工作集页面置换算法(工作集:一个进程当前正在使用的页面的集合。预先调页)
9) 工作集时钟页面置换算法(WSClock)
14. 分页系统中的设计问题
1) 局部分配策略与全局分配策略
全局算法通常情况下工作得比局部算法好
PFF算法(缺页中断率算法):管理内存动态分配,尽力让每个进程的缺页中断率控制在可接受的范围内
适用于局部又适用于全局:FIFO、LRU
只适于局部:工作集、WSClock
2) 负载控制
一旦所有进程的工作集超出了内存容量,就可能发生颠簸,即使采用最优算法。
解决办法:将一部分进程交换到磁盘,并释放它们占有的所有页面。
3) 页面大小
最优页面大小公式 P=sqrt(2se) (进程平均大小是s字节,每个页表项需要e字节)
4) 分离指令空间和数据空间
5) 共享页面
写时复制,两个进程通过共享程序页表,来共享同一程序。
6) 共享库
位置无关代码,解决重定位出错的问题。
7) 内存映射文件
共享库实际上是一种更为通用的机制----内存映射文件的一个特例。
进程可以通过发起一个系统调用,将一个文件映射到其虚拟地址空间的一部分。
在多数实现中,在影射共享的页面时不会实际读入页面的内容,而是在访问页面时才会被每次一页地读入,磁盘文件则被当作后备存储.但进程退出或显式地解除文件映射时,所有被改动的页面会被写回文件中。
8) 清除策略
分页守护进程:定期检查内存状态,如果空闲页框太少,置换。如果置换的页面被修改过,写回磁盘。
双指针时钟:前指针由分页守护进程控制,指向脏页面时,写回前移,否则只前移。后指针用于页面置换。
15. 有关实现的问题
1) 分页相关工作的时间:进程创建时,进程执行时,缺页中断时和程序终止时。
2) 缺页中断处理的时间顺序
缺页中断发生时的事件顺序如下:
1. 硬件陷入内核,在堆栈中保存程序计数器。大多数机器将当前指令的各种状态信息保存在特殊的CPU寄存器中。
2. 启动一个汇编代码例程保存通用寄存器和其他易失的信息,以免被操作系统破坏。这个例程将操作系统作为一个函数来调用。
3. 当操作系统发现一个缺页中断时,尝试发现需要哪个虚拟页面。通常一个硬件寄存器包含了这一信息,如果没有的话,操作系统必须检索程序计数器,取出这条指令,用软件分析这条指令,看看它在缺页中断时正在做什么。
4. 一旦知道了发生缺页中断的虚拟地址,操作系统检查这个地址是否有效,并检查存取与保护是否一致。如果不一致,向进程发出一个信号或杀掉该进程。如果地址有效且没有保护错误发生,系统则检查是否有空闲页框。如果没有空闲页框,执行页面置换算法寻找一个页面来淘汰。
5. 如果选择的页框“脏”了,安排该页写回磁盘,并发生一次上下文切换,挂起产生缺页中断的进程,让其他进程运行直至磁盘传输结束。无论如何,该页框被标记为忙,以免因为其他原因而被其他进程占用。
6. 一旦页框“干净”后(无论是立刻还是在写回磁盘后),操作系统查找所需页面在磁盘上的地址,通过磁盘操作将其装入。该页面被装入后,产生缺页中断的进程仍然被挂起,并且如果有其他可运行的用户进程,则选择另一个用户进程运行。
7. 当磁盘中断发生时,表明该页已经被装入,页表已经更新可以反映它的位置,页框也被标记为正常状态。
8. 恢复发生缺页中断指令以前的状态,程序计数器重新指向这条指令。
9. 调度引发缺页中断的进程,操作系统返回调用它的汇编语言例程。
10. 该例程恢复寄存器和其他状态信息
3) 指令备份:当程序访问不在内存中的页面时,将引起页面失效的指令停止并产生OS的陷阱。
解决方案:使用隐藏的内部寄存器复制程序计数器的内容
4) 锁定内存中的页面
5) 后备存储:静态、动态、交换分区
16. 分段:用于各种表的扩张、收缩管理
在机器上提供多个互相独立的称为段的地址空间。
段是一个逻辑实体,段的长度可以是0到某个允许的最大值。
分段有助于在几个进程之间共享过程和数据。
页面时定长的而段不是。
17. 分段和分页结合:MULTICS
一个地址分为:段和段内地址。
段内地址:页号和页内的字(页内偏移量)
MULTICS包含16个字的高速TLB
18. 分段和分页的结合:Pentium
LDT局部描述符表:每个程序的段,代码、数据、堆栈等
GDT全局描述符表:系统段,包括操作系统本身