操作系统精髓与设计原理
操作系统精髓与设计原理(第七版)
存储器地址寄存器(Memory Address Register,MAR)
存储器缓存寄存器(Memory Buffer Register,MBR)
输入输出地址寄存器(I/O Address Register,I/O AR或IO地址寄存器)
输入输出缓冲寄存器(I/O Buffer Register,I/O BR或I/O缓冲寄存器)
程序计数器(Program Counter,PC)
指令寄存器(Instruction Register,IR)
中断(interrupt),提高处理器效率的一种手段。
存储器的层次结构(memmory hierarchy)
命中率(hit ratio)
二级存储器(secondary memory)或者辅助存储器(auxiliary memory)
局部性原理(principle of locality)
块(blocks)
存储槽(slots)
映射函数(mapping function)
置换算法(raplacement algorithm)
写策略(write policy)
chapter 3 进程
把进程视为由一组元素组成的实体,进程的两个基本元素是程序代码(program code,可能被执行相同程序的其他进程共享)和代码相关的数据集(set of data)。假设处理器开始执行这个进程,在进程执行时,任意给定一个时刻,进程都可以唯一的表征为以下元素:
- 标识符:进程的唯一标识符。
- 状态:运行态、阻塞态等。
- 优先级:
- 程序计数器:程序中将被执行的下一条指令的地址。
- 内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享内存块的指针。
- 上下文数据:进程执行时处理器的寄存器中的数据。
- I/O状态信息:包括显式的I/O请求、分配给进程的I/O设备和被进程使用的文件列表等。
- 记账信息:可能包括处理器时间总和、使用的时钟数总和、时间限制、记账号。
进程控制块包含了以上的信息,使得进程之间可以进行切换。因此可以说,进程是由程序代码和相关数据还有进程控制块组成。
进程的轨迹(trace)
分派器(dispatcher)
进程派生(process spawning)父进程、子进程
交换(swapping):一个I/O操作、
挂起队列(suspend queue)
调度(schedule)分派(dispatch)
内存表(memory table)
I/O表(I/O table)
文件表(file table)
进程表(process table)
进程映像(process image):程序、数据、栈和进程控制块中定义的属性的集合。
进程控制块(process control block,PCB)
进程标识符(process identification)
处理器状态信息(processor state information)
用户态(user mode)
系统态(system mode)、控制态(control mode)、内核态(kernel mode)
上下文切换(context switch):也称环境切换或者进程切换。需要改变并且保存进程控制块,是的来回切换时能迅速定位到进程。
进程切换的具体步骤:
1. 保存处理器上下文环境,包括程序计数器和其他寄存器。
2. 更新当前运行态进程的进程控制块,包括将进程的状态改变到另一状态,还必须更新其他相关域。
3. 将进程的进程控制块移到相应的队列。
4. 选择另一个进程执行。
5. 更新所选择的进程的进程控制块,包括将进程的状态改为运行态。
6. 更新内存管理的数据结构(后续将会讲到)
7. 恢复处理器在被选择的进程最近一次切换出运行状态的上下文环境,这可以通过载入程序计数器和其他寄存器以前的值来实线。
chapter 4 线程
进程:拥有资源所有权,可被操作系统调度和分派的实体。
分派的最小单位成为线程或轻量级进程(Light Weight Process,LWP),而拥有资源所有权的单位通常仍称为进程或任务(task)。
进程涉及资源的所有权,线程涉及程序的运行。在多线程系统中,可以在一个进程内定义多个并发线程。这可以通过使用用户级线程或内核级线程来完成。用户级线程对操作系统是未知的,他们由一个在进程的用户空间中运行的线程库创建并管理。用户级线程是非常高效的,因为切换线程不需要状态转换,但是一个进程中一次只有一个用户级线程可以运行,如果线程发生阻塞,整个进程都会被阻塞。内核级线程由内核维护,同一个进程中的多个线程可以在多个处理器上并行执行,一个线程的阻塞不会阻塞整个进程,但当从一个线程切换到另一个线程时需要模式转换。
chapter 5 并发性:互斥和同步
临界资源(critical resource):只允许一个进程访问的资源。
临界区(critical section)
死锁(deadlock)
饥饿(starvation)
entercritical
exitcritical
互斥的要求:
1. 必须强制实施互斥
2. 一个在非临界区停止的进程不能干涉其他的进程。
3. 决不允许出现需要访问临界区的进程被无限延迟的情况,即不会出现死锁和饥饿、
4. 当没有进程在临界区时,任何需要进入临界区的进程必须能够进入。
5. 对相关进程的执行速度和处理器的数目没有任何的要求和限制。
6. 一个进程驻留在临界区中的时间必须是有限的。
互斥:硬件的支持
- 禁用中断:对单处理系统管用,多处理系统不管用。
- 专用机器指令: 比较和交换指令
互斥机器指令:比较和交换指令(compare and swap instruction)或(compare and exchange instruction)原子操作,不接受中断。
5.3 信号量(semaphore)
信号量是1965荷兰Dijkstra为了解决并发进程问题而提出的一个重要操作系统的思想。进程间进行通信的一种媒介之一。
其基本思想:
两个或多个进程可以通过简单的信号进行合作,一个进程可以被迫在某个位置停止,直到它接收到一个特定的信号。任何复杂的合作需求都可以通过适当的信号结构得到满足。为了发信号,需要使用一个称为信号量的特殊变量。为通过信号量s发送信号,进程可执行原语semSignal(s),即V操作;为了通过信号量s接收信号,进程可执行原语semWait(s),即P操作;如果相应的信号还没有发送,则进程将被挂起,直至发送为止。
信号量可被看做死一个具有整数型的变量,有三个操作:
一个信号量可以初始化成非负数,一般资源数就是信号量的初始值
semWait操作,即P操作,使得信号量减1,如果值变成负数(s <0) 则执行semWait的进程被阻塞,否则进程继续执行
semSignal操作,即V操作,使得信号量加1,如果值小于或等于零,则被semWait操作阻塞的进程被解除阻塞
using namespace std;
struct semaphore{
int count;
queueType queque;
}
void semWait(semaphore s){//P操作
s.count--;
if(s.count<0){
place this process in s.queue;
block this process;
}
}
void semSignal(semaphore s){//V操作
s.count++;
if(s.count<=0){
remove a process P from s.queque;
place process P on ready list;
}
}
开始时,信号量的值为零或正数,如果该值为正数,则该值等于发出semWait操作之后还能继续执行的进程数,如果该值为零,则发生semWait操作后的下一个进程就将会被阻塞。此时该信号量的值变为负。此后每一个semSignal操作都会为处于阻塞状态的一个进程解除阻塞。
二元信号量(binary semaphore)
一个二元信号量可以初始化成0或1。
非二元信号量被称为计数信号量或一般信号量。
互斥量
为互斥量加锁(设置为1)的进程和为互斥量解锁(设置0)的进程必须是同一个,相比之下,二元信号量没有限制是同一个进程。
强信号量(strong semaphore):阻塞最久最先释放
弱信号量(weak semaphore):不是队列移除
5.4 管程
管程是一个程序设计语言结构,它提供了与信号量同样的功能,但更易于控制。
管程是由一个或多个过程、一个初始化序列和局部数据组成的软件模块。主要特点:
1. 局部数据变量只能被管程的过程访问,任何外部过程都不能访问。
2. 一个进程通过调用管程的一个过程进入管程。
3. 在任何时候,只能有一个进程在管程中执行,调用管程的任何其他进程都被阻塞,以等待管程可用。
对于管程而言,它构造自己的互斥机制。但是同步还是需要程序员在程序上自己实现。
而对于信号量,执行互斥和同步都需要程序员去实现。
管程优于信号量之处在于,所有的同步机制都被限制在管程内部,因此,不但易于验证同步的正确性,而且易于检测出错误。此外,如果一个管程被正确地编写,则所有进程对受保护资源的访问都是正确的;而对于信号量,只有当所有访问资源的进程都被正确地编写时,资源访问才是正确的。
5.5 消息传递
send、receive
发送者和接受者都可以阻塞和不阻塞。特定的系统实现不同的组合:
- 阻塞send、阻塞receive:
- 无阻塞send、阻塞recieve:发送者尽快的发送,接受者必须接受到消息。
- 无阻塞send、无阻塞receive
寻址
直接寻址和间接寻址
间接寻址:消息不是直接从发送者发送到接受者,而是发送一个共享数据结构,成为信箱(mailBox)。
一对一、多对一、一对多或多对多寻址。多对一的信箱又可称为端口(port)。
5.6 读者/写者问题
- 任意多的读进程可以同时读这个文件。
- 一次只有一个写进程可以写文件。
- 如果一个写进程正在写文件,那么禁止任何读进程读文件。
chapter 6 并发:死锁和饥饿
死锁的条件:
三个必要条件
1. 互斥:一次只有一个进程可以访问一个资源。
2. 占有且等待:当一个进程等待其他进程时,继续占有已经分配的资源。
3. 不可抢占:不能强行抢占进程已占有的资源。
充分条件:
4. 循环等待:存在一个封闭的进程链,使得每个进程至少占有下个进程所需要的一个资源。
6.2 死锁的预防
prevention。从4个充要条件下手。P190
6.3 死锁的避免
允许三个必要条件,通过明智的选择,确保永远不会到达死锁点,因此死锁避免(deadlock avoidance)比死锁预防允许更多的并发。
两种避免死锁的方法:
- 如果一个进程的请求会导致死锁,则不会启动此进程。
- 如果一个进程增加的资源请求会导致死锁,则不允许此分配。
进程启动拒绝
只有所有当前进程的最大请求量家还是那个新的进程请求可以满足时,才会启动该进程。
资源分配拒绝
资源分配拒绝策略又称银行家算法
新概念:安全状态:至少有一个资源分配序列不会导致死锁。即剩余的资源至少可以满足一个进程的资源需求。具体见P192
6.4 死锁的检测
6.6 哲学家就餐
哲学家就餐问题可以这样表述,假设有五位哲学家围坐在一张圆形餐桌旁,做以下两件事情之一:吃饭,或者思考。吃东西的时候,他们就停止思考,思考的时候也停止吃东西。餐桌中间有一大碗意大利面,每两个哲学家之间有一只餐叉。因为用一只餐叉很难吃到意大利面,所以假设哲学家必须用两只餐叉吃东西。他们只能使用自己左右手边的那两只餐叉。哲学家就餐问题有时也用米饭和筷子而不是意大利面和餐叉来描述,因为很明显,吃米饭必须用两根筷子。
哲学家从来不交谈,这就很危险,可能产生死锁,每个哲学家都拿着左手的餐叉,永远都在等右边的餐叉(或者相反)。即使没有死锁,也有可能发生资源耗尽。例如,假设规定当哲学家等待另一只餐叉超过五分钟后就放下自己手里的那一只餐叉,并且再等五分钟后进行下一次尝试。这个策略消除了死锁(系统总会进入到下一个状态),但仍然有可能发生“活锁”。如果五位哲学家在完全相同的时刻进入餐厅,并同时拿起左边的餐叉,那么这些哲学家就会等待五分钟,同时放下手中的餐叉,再等五分钟,又同时拿起这些餐叉。
在实际的计算机问题中,缺乏餐叉可以类比为缺乏共享资源。一种常用的计算机技术是资源加锁,用来保证在某个时刻,资源只能被一个程序或一段代码访问。当一个程序想要使用的资源已经被另一个程序锁定,它就等待资源解锁。当多个程序涉及到加锁的资源时,在某些情况下就有可能发生死锁。例如,某个程序需要访问两个文件,当两个这样的程序各锁了一个文件,那它们都在等待对方解锁另一个文件,而这永远不会发生。
协调处理共享资源
6.6.1 基于信号量解决方案
6.6.2 基于管程的解决方案
6.7 UNIX的并发机制
UNIX中进程之间的通信和同步机制:
- 管道
- 消息
- 共享内存
- 信号量
- 信号
管道、消息、共享内存提供进程之间传递数据的方法,信号量、信号用于出发其他进程的行为。
6.11 小结
死锁指一组争用系统资源或相互通信的进程被阻塞的现象,这种阻塞是永久的,除非操作系统采取某些非常的行动,如杀死一个进程,或者强迫多个一个或者多个进程进行回滚。死锁可能涉及可重用资源部或可消耗资源。可重用资源是指不会因为使用而被耗尽或销毁的资源,如I/O通道或一块内存区域。可消耗资源是指当被一个进程获得时就销毁了的资源,这类资源的例子有消息和I/O缓冲区中的信息。
处理死锁通常有三种方法:预防、检测和避免。死锁预防通过确保死锁的一个必要条件不会满足,保证不会发生死锁。如果操作系统总是同意资源请求,则需要进行死锁检测,操作系统必须周期性的检查死锁,并采取行动打破死锁。死锁避免设计分析新的资源请求,以确定他是否会导致死锁,并且只有当不可能发生死锁时才同意该请求。
chapter 7 内存管理
二级存储:计算机主存储器或内存之外的所有可访问数据存储器。外部存储以及辅助存储是其同义词。
7.1 内存管理的需求
- 重定位:挂起的进程重新进入到内存时需要重定位到内存的不同区域。
- 保护:防止本进程以外的其他进程中的程序未经允许访问该进程的内存单元。因此,在进程中必须检查进程所访问的所有内存地址,以确保它们只访问了分配给改进程的内存空间。由处理器处理违法内存访问比操作系统处理更加快速高效。
- 共享:保护机制必须具备一定的灵活性,以确保能够访问共享内存区域,而不会损害基本的保护。
- 逻辑组织:大多数程序在结构上被组织成模块,这种逻辑上的结构如何在内存中被处理衍生出了很多的技术。
- 物理组织:内存和外存之间信息流的组织和传递,存储管理的本质。
7.2 内存分区
7.2.1 固定分区
- 大小相等的分区:大小有限;利用率低,会产生内部碎片(internal fragmentation)。
- 大小不等的分区:缓解以上的问题。也有别的问题存在。P222.目前很少有系统采取这种分区方式。
7.2.2 动态分区
内存分配个进程的大小是按需分配,不多不少,在多次进行进程的挂起运行之后会在内存中出现很多“洞”。称为外部碎片(external fragmentation):只在所有分区外的存储空间变成越来越多的碎片,这与前面内部碎片刚好相对应。
解决外部碎片
- 压缩:由处理器移动进程,腾出空余的连续的内存空间,缺点是浪费处理器资源,并且要支持动态重定位。
- 放置算法:当碎片累计到一定量时,需要将进程放入到碎片内存中来减少内存,放置的算法有:最佳适配、首次适配、下次适配。P224
- 置换算法:涉及到将内存中处于阻塞状态的进程置换出内存以给新进程或者就绪/挂起态进程腾出空间的操作,涉及到虚拟内存。
7.2.3 伙伴系统
固定分区和动态分区都不好,这种方案是伙伴系统。
伙伴系统:需要分配空间时, 采用除以2的方式确定需要分配的空间大小,从同一空间分割出来的子空间称为伙伴空间,相同大小的伙伴空间之间具有合并的趋势。(即不存在两个都为空的伙伴空间)
在现代系统中,基于分页和分段机制的虚拟内存方案更加先进,因此上述的三种方案在现在已经很少用到了。
7.2.4 重定位
当进程在内存中移动时,指令和数据单元的位置会发生改变,需要区分几种地址类型:
- 逻辑地址(logic address):指与物理地址无关的访问地址,在执行对内存的访问之前必须将其转换成物理地址。
- 相对地址(relative address):是逻辑地址的一个特例,相对于某个已知地质点的存储单元。
- 物理地址(physical address):内存中的实际位置。
基址寄存器,保存着程序的起始地址,界限寄存器指明程序的终止位置。负责将相对地址安全地转换为物理地址,因此处理器负责转化成物理地址。
7.3 分页
将内存分为页框或者帧(frame)的内存块,将进程分为页(page)的块。
每个进程中维护了一个页表(page table),维护了每一个页对应的页框的位置。
程序中,逻辑地址是一个页号和在该页中的偏移量。处理器使用页表产生物理地址。采用分页技术的分区相当小,一个程序可以占据多个分区,并且这些分区不需要是连续的。
采用简单分页技术,内存被分成许多大小相等且很小的页框,每个进程被划分成同样大小的页;较小的进程需要较少的页,较大的进程需要较多的页;当一个进程被装入时,它的所有页都被装入到可用页框中,并且建立一个页表,用于处理器由逻辑地址索引到物理地址。这种技术解决了分区技术中存在的很多问题。
7.4 分段
把程序和其相关的数据划分到几个段(segment)中。
分段技术逻辑地址:段号和偏移量。
采用简单分段技术,进程被分为很多段,段的大小不需要相等;当一个进程被调入时,它的所有段都被装入内存的可用区域中,并建立一个段表。段表维护相应段号在内存中的起始位置,并指明了该段的长度。寄存器由逻辑地址提取段号和最大段长度,与段表中的段号索引,找到内存中的位置。
chapter 8 虚拟内存
你需要一艘更大的船。——《大白鲨》
8.1 硬件和控制结构
突破口:
1. 进程中的所有内存访问都是逻辑地址,这些逻辑地址在运行时动态的被转换成物理地址,这意味着一个进程可以被换入或换出内存,使得进程可以在执行过程中的不同时刻占据内存中的不同区域。
2. 一个进程可以划分成许多块(页和段),在执行过程中,这些块不需要连续的位于内存中。动态运行时地址转换和页表或段表的使用使这一点成为可能。
常驻集(resident set):进程执行中的任何时刻都在内存中的部分称为进程常驻集。将页或者段成为进程块。
当请求的逻辑地址不在内存中时,则产生一个中断,将中断的进程置为阻塞,并将包含引发访问故障的逻辑地址的进程读入内存,再讲该进程置为就绪态。
常驻集带来的好处:
1. 在内存中保留更多的进程:对于每个进程仅仅保留了必要的部分(常驻集),因此有足够的空间保留更多的进程,保证在任何时刻都有处于就绪态的进程,使得处理器的效率更高。
2. 进程可以比内存的全部空间还大:因为内存中只保存了进程的常驻集。
实存(real memory)、虚存(virtual memory)
系统抖动(thrashing):当系统在读取一块时,移除了另一块B,若B块即将执行,即又不得不再读回来,这种现象称为系统抖动,处理器的大部分时间都用于交换块,而不是执行块。如果减少系统抖动出现了很多复杂且高效的算法。大多基于局部性理论(principle of locality):局部性理论描述了一个进程中程序和数据的聚簇倾向。
8.1.2 分页
当一个进程中的所有页都读入到内存时,在内存中针对每一页的维护一个页表项(Page Table Entry,PTE),存储页和页框(帧)的对应信息。
页表结构:每一个进程中有唯一的页表,用于维护每一页对应的相关信息。页表中保存有虚拟地址(逻辑地址)包括页号和偏移量,物理地址则有帧号和偏移量组成。根据虚拟地址的页号索引页表找到相应的帧号,再根据虚拟地址的偏移量结合帧号得出物理地址。
由于一个进程可能存在很多个页,因此页表中可能会出现多个页表项,保存在实存中将会占用巨大的空间,通常将页表保存在虚拟内存中。因此,页表和部分页都存储在虚拟内存中,即服从分页管理。当一个进程正在运行时,它的页表至少有一部分必须在内存中,这一部分包括正在运行的页的页表项。
根页表:用于映射页表
用户页表:用于映射虚拟地址空间。
根页表—–>用户页表——>虚拟内存地址
两级结构能有效减少信息存储量。详见P247
针对32位虚拟地址,前10位用于检索根页表,得用户页表(假设不用中断),再10位检索得到的用户页表,得页表项,后12位用于寻址到内存(实存)。
倒排页表:使用散列技术将页号均匀分布给页框。
每个虚存访问可能引起两次物理内存访问:一次取对应的页表项,一个取需要的数据。因此,简单的虚拟内存方案会导致内存访问时间加倍。
解决办法:为页表项使用一个特殊的高速缓存,通常称为转换检测缓冲区(Translation Lookaside Buffer,TLB),这个高速缓存的功能和高速缓冲存储器相似,包含了最近用过的页表项。
当访问一个虚拟地址时,经过的步骤为:
1. 给定一个虚拟地址,处理器首先检查TLB,如果需要的页表项在其中(TLB命中),则检索帧号并形成实地址。
2. 否则,处理器用页号检索进程页表,如果存在,则处理检索出的帧号形成实地址。处理器同时更新TLB,使其包含新的页表项。
3. 如果进程页表中不存在该页号,则产生一次内存访问故障,称为缺页(pagefault)中断。此时离开硬件作用的范围,调用操作系统,由操作系统负责装入所需要的页,并更新页表。
由于TLB表仅包含了整个页表中的部分表项,因此处理器中的硬件机制允许同时查询许多TLB页,以确定是否存在匹配的页号。
虚拟机制还与内存中的高速缓存(不是TLB)进行了交互。当获取到实地址时,会与高速缓存进行检索,查到该块直接交给CPU,否则再从内存中查找。
一次内存访问中涉及到CPU硬件的复杂性。虚拟地址被转换为实地址,这涉及访问页表项,而页表项可能在TLB中,也可能在内存中或磁盘中,被访问的块可能在高速缓存中、内存中或磁盘中。如果被访问的字只在磁盘中,则包含改字的页必须装入内存,并且它所在的块装入到高速缓存中。此外,包含改字的页对应的页表项必须被更新。
8.1.3 分段
简单分段时:每个进程有自己的段表,当它的所有段都装入内存时,为该进程创建一个段表并装入内存。每个段表项包含相对应段在内存中的起始位置和段的长度。
虚拟内存分段:每个进程也有自己的唯一段表。段表项变得更复杂而已。
8.1.4 段页式
分页对程序员是透明的,它消除了外部碎片,因而可以更有效的利用内存。
分段对程序员是可见的,它具有处理不断增长的数据结构的能力以及支持共享和保护的能力。
段页式的系统中,用户的地址空间被程序员划分为许多段,每个段一次划分为许多固定大小的页,页的长度等于内存中的帧的大小。从程序员的角度看,逻辑地址仍然是由段号和段偏移量组成;从系统的角度看,段偏移量可视为指定段中的一个页号和页偏移量。
段页式的工作过程:
每个进程使用一个段表和一些页表,并且每个进程段中使用一个页表。当一个特定的进程运行时,使用一个寄存器记录该进程表的起始地址。对每一个虚拟地址,处理器使用段号部分来检索进程段表以寻找该段的页表,然后虚拟地址的页号部分用于检索页表中的帧号,再结合虚拟地址的偏移量来产生需要的实地址。
8.2 操作系统软件
操作系统的内存管理设计取决于三个基本方面的选择:
- 是否使用了虚存技术
- 是使用分页还是使用分段,或者是两者的结合
- 为各种存储管理特征采用的算法
前两个是硬件相关,第三个是操作系统相关
8.2.1 读取策略
- 请求分页(demand paging):当访问到某页中的一个单元时才将该页取入内存,当进程第一次启动时,讲出现大量的缺页中断。
- 预先分页(prepaging):读取的页并不是缺页中断请求的页。读取连续的页或一定间隔的页。
8.2.3 置换策略
基本算法:
- 最佳(Optimal,OPT):置换下次访问距当前时间最长的那些项。
- 最近最少使用(Least Recently Used,LRU):置换内存中上次使用距当前最远的页
- 先进先出(First In First Out,FIFO):循环缓冲区,实现简单,但是性能低,将导致更多的缺页中断。
- 时钟(Clock):以较小的开销接近LRU性能的一种算法。
驻留集的大小:
- 固定分配策略:固定大小
- 可变分配策略:可调的,动态变化的。
置换范围:
- 局部置换策略(local replacement policy):产生这次缺页的同一进程的驻留页中选择。
- 全局置换策略(global replacement policy):所有未锁定的页做为置换页的候选。
置换范围和驻留级的大小有一定的联系:固定驻留级意味着页框的大小不变,因此采取局部置换策略。可变分配策略采取全局置换策略。此外:可变分配+局部置换也是可行的。
8.2.5清除策略
清除策略和读取策略相反,它用于何时将一个修改过的页写回辅存。
- 请求式清除:只有当一页被选择用于置换时才被写回辅存。
- 预约式清除:将这些被修改的多个页在需要用到他们所占据的页框之前成批的写回辅存。
8.6 小结
使用虚拟内存技术的原因:为了有效地使用处理器和I/O设备,希望能在内存中保留尽可能多的进程。此外,还希望能解除程序开发时对程序所使用的内存大小的限制。
虚拟内存技术,所有的访问都是逻辑地址访问,在运行时转换为实地址。允许一个进程位于内存中的任何地址,并且可以随着时间而变化。
允许一个进程被划分成块,这些块在内存中不需要是连续的,并且在运行中,不需要进程所有的块都在内存中。
分页技术:每个进程划分成相对比较小且大小固定等于页框大小的页。
分段技术:进程被划分为大小可变的块。 分页和分段技术可以组合到同一个内存管理方案中。
与操作系统对内存管理的支持相关的设计问题有:
- 读取策略:
- 放置策略:
- 置换策略:
- 驻留集策略:
- 清除策略:
- 加载控制: