操作系统之内存管理

1.背景

1.1 基本硬件

Q1:如何确保每个进程有独立的内存空间,确定进程可访问的合法地址的范围?

A1:采用基地址寄存器界限地址寄存器。基地址寄存器含有最小的合法物理内存地址,界限地址寄存器决定范围大小。如基地址寄存器为300040,界限地址寄存器为120900,则程序可访问地址范围为300040至420940(含)的所有地址。

如图所示:

Q2:如何实现对内存空间的保护?

A2:通过CPU硬件对用户模式下所产生的每一个地址与寄存器的地址进行比较来完成。如用户模式下执行的程序试图访问操作系统内存或其他用户内存,则会陷入操作系统,作为致命错误处理。见图所示:

1.2 地址绑定

Q1:什么是输入队列

A1:程序以二进制可执行文件的形式存储在磁盘上,为了执行,程序被调入内存并放在进程空间内,根据所使用的内存管理方案,进程在执行时可以在磁盘和内存之间移动,在磁盘上等待调入内存以便执行的进程形成输入队列。通常的步骤是从输入队列选取一个进程并装入内存,进程在执行时,会访问内存中的指令和数据,最后进程终止,其地址空间被释放。

Q2:什么是地址绑定?

A2:首先看程序的处理过程,见图:

      源程序中的地址通常是用符号(如count)来表示,编译器通常将这些符号地址绑定(bind)在可重定位的地址(如:从本模块开始的第14字节)。链接程序或加载程序再将这些可重定位的地址绑定成绝对地址(如74014)。每次绑定都是从一个地址空间到另一地址空间的映射。

通常,将指令与数据绑定到内存地址有以下几种情况:

  • 编译时(compile time):若编译时知道进程将在内存中的驻留地址,可以生成绝对代码(absolute code)。如果将来开始地址发生变化,那么就必须重新编译代码。

  • 加载时(load time):当编译时不知道进程将驻留在内存的什么地方,编译器必须生成可重定位代码(reloadable code)。绑定会延迟到加载时才进行。如果开始地址发生变化。只需要重新加载用户代码以引入改变值。

  • 执行时(execution time):如果进程在执行时可以从一个内存段移到另一个内存段,那么绑定必须延迟到执行时才发生。绝大多数通用计算机操作系统采用这种方法。

1.3 逻辑地址空间与物理地址空间(都是些概念)

逻辑地址(虚拟地址):CPU生成的地址;

物理地址:内存单元所看到的地址(即加载到内存地址寄存器(memory-address register)中的地址);

逻辑地址空间:由程序所生成的所有逻辑地址的集合;

物理地址空间:与逻辑地址相对应的物理地址的集合;

Q1:如何在运行时从虚拟地址到物理地址映射?

A1:靠一个硬件设备——内存管理单元(memory-management unit,MMU)。基地址寄存器在这里称为重定位寄存器(relocation register),用户进程所生成的地址在送交内存之前,都加上重定位寄存器的值。假如,基地址为14000,那么用户对地址346的访问将映射为地址14346。

如图所示:PS:用户不会看到真正得物理地址。

1.4 动态加载:

     一个子程序只有在调用时才被加载。所有的子程序都以可重定位的形式保存在磁盘上。主程序装入内存并执行。当一个子程序需要调用另外一个子程序的时候,调用子程序首先检查另一个子程序是否已经被加载。如果没有,可重定位的链接程序将用来加载所需要的子程序,并更新程序的地址表以反应这一变化。接着控制传递给新加载的子程序。

     优点:不会加载不用的子程序。考虑一段程序中含有大量的异常处理代码,但这些异常处理子程序很少需要。

1.5 动态链接:(看他人的博客)

      Q1:什么是静态链接?

      A1:在链接阶段,将源文件中用到的库函数与汇编生成的目标文件.o合并生成可执行文件。该可执行文件可能会比较大。优点:方便程序移植,因为可执行程序与库函数再无关系。缺点是:文件太大。如图所示说明:

      

Q2:什么是动态加载?

A2:将链接延迟到运行时。通常用于系统库。

     如果有动态链接,二进制镜像中每个库程序的应用都有一个存根(stub)。存根是一小段代码,用以指出如何定位适当的内存驻留的库程序,或如果该程序不在内存中应如何安装入库。不管怎样,存根会用子程序地址来代替自己,并开始执行子程序。因此,下次再执行该子程序代码时,就可以直接进行,而不会因动态链接产生任何开销。采用这种方案,使用语言库的所有进程只需要一个库代码副本就可以了。见图:

在这种模型中,两个程序只应用一个库,这个目标文件在内存中只有一份,供所有程序使用。

并且在程序运行过程中动态调用库文件,很方便,又不占空间,但是动态链接有一个缺点就是可移植性太差。

2.交换

基本思想:把处于等待(阻塞)状态(或在CPU调度原则下被剥夺运行权利)的程序(进程)从内存移到辅存(外存),把内存空间腾出来,这一过程又叫换出。把准备好竞争CPU运行的程序从辅存移到内存,这一过程又称为换入。中级调度(策略)就是釆用交换技术。

举例:交换策略的变种被用在基于优先级的调度算法中。如果有一个更高优先级的进程且需要服务,内存管理器可以交换出低优先级的进程,以便装入和执行更高优先级的的进程。当高优先级进程执行完后,低优先级进程可以交换回内存继续执行。

2.1 交换需要备份存储:通常是快速磁盘,容纳所有用户的内存镜像副本,提供对这些内存镜像的直接访问。

就绪队列(感觉和输入队列类似):包括在备份存储或内存中等待运行的所有进程。当CPU调度程序决定执行进程时,它调用调度程序。调度程序检查队列中的下一进程是否在内存中,如果不在内存中且没有空闲内存空间,调度程序将一个已在内存中的进程交换出去,并换入所需要的进程。然后,它重新装载寄存器,并将控制转交给所选择的进程。

2.2 上下文切换时间比较长

2.3 受其他因素限制,如果要换出进程,那么必须确保该进程完全处于空闲状态。尤其注意待处理I/O。

2.4  交换空间通常作为磁盘的一整块,且独立与文件系统,因此使用就可能很快。通常并不执行交换,但当有许多进程运行且内存空间吃紧时,交换开始启动。如果系统负荷降低,交换就暂停。

猜你喜欢

转载自www.cnblogs.com/dzy521/p/9385022.html