操作系统——内存管理
作者:互联网
一、内存管理基本原理
内存管理功能
- 负责内存空间的分配与回收
- 提供某种技术从逻辑上对内存空间进行扩充
- 提供地址转换功能,负责程序的逻辑地址与物理地址的转换
- 提供内存保护功能。保证各进程在各自存储空间内运行,互不干扰
程序的装入和链接
程序的链接有以下三种方式:
-
静态连接 :在程序运行之前,先将各目标模块及它们所需的库函数连接成一个完整的可执行文件(装入模块),之后不再拆开。
-
装入时动态链接 : 将各目标模块装入内存时,边装入边链接的链接方式。
-
运行时动态链接 :在程序执行中需要该目标模块时,才对它进行链接。其优点是便于修改和更新,便于实现对目标模块的共享。
内存的装入模块在装入内存时同样有以下三种:
- 绝对装入 : 在编译时,如果知道程序将放到内存中的哪个位置,编译程序将产生绝对地址的目标代码。装入程序按照装入模块中的地址,将程序和数据装入内存。
绝对装入只适用与单道批处理系统。
- 静态重定位 : 编译、链接后的装入模块的地址都是从0开始的,指令中使用的地址、数据存放的地址都是相对于起始地址而言的逻辑地址。可根据内存的当前情况,将装入模块装入到内存的适当位置。装入时对地址进行“重定位”,将逻辑地址变换为物理地址(地址变换是在装入时一次完成的)。
- 动态重定位 : 编译、链接后的装入模块的地址都是从0开始的。装入程序把装入模块装入内存后,并不会立即把逻辑地址转换为物理地址,而是把地址转换推迟到程序真正要执行时才进行。因此装入内存后所有的地址依然是逻辑地址。这种方式需要一个重定位寄存器的支持。
逻辑地址空间与物理地址空间
编译后,每个目标模块都从0号单元开始编址,这称为目标模块的相对地址(逻辑地址)。当链接程序将各个模块链接成一个完整的可执行目标程序时,链接程序顺序依次将各个模块的相对地址统一成从0号单元开始编址的逻辑地址空间。
不同的进程可以有相同的逻辑地址。
物理地址空间是指内存中物理单元的集合。它是地址转换的最终地址。进程在运行时执行指令和访问数据,最后都要通过物理地址从主存中存取。
通过地址转换将逻辑地址变为物理地址,这个过程称为地址的重定位
。
内存保护
方法一 : 在CPU中设置一对上、下限寄存器,存放进程的上、下限地址。进程的指令要访问某个地址时,CPU检查是否越界。
方法二 : 采用重定位寄存器(又称基址寄存器)和界地址寄存器(又称限长寄存器)进行越界检查。重定位寄存器中存放的是进程的起始物理地址。界地址寄存器中存放的是进程的最大逻辑地址。
二、覆盖与交换
两者之间的区别 : 覆盖是在同一个程序或进程中的。交换是在不同进程(或作业)之间的。
覆盖
将程序分为多个段(多个模块)。常用的段常驻内存,不常用的段在需要时调入内存。
内存中分为一个“固定区”和若干个“覆盖区”。
需要常驻内存的段放在“固定区”中,调入后就不再调出(除非运行结束)
不常用的段放在“覆盖区”,需要用到时调入内存,用不到时调出内存。
交换
内存空间紧张时,系统将内存中某些进程暂时换出外存,把外存中某些已具备运行条件的进程换入内存(进程在内存与磁盘间动态调度)。暂时换出外存等待的进程状态为挂起状态。
三、连续分配管理方式
单一连续分配
固定分区分配
20世纪60年代出现了支持多道程序的系统,为了能在内存中装入多道程序,且这些程序之间又不会相互干扰,于是将整个用户空间划分为若干个固定大小的分区,在每个分区中只装入一道作业。
分区大小相等 : 缺乏灵活性,但是很适合用于用一台计算机控制多个相同对象的场合。
分区大小不等 : 增加了灵活性,可以满足不同大小的进程需求。根据常在系统中运行的作业大小情况进行划分。
动态分区分配
动态分区分配又称为可变分区分配。这种分配方式不会预先划分内存分区,而是在进程装入内存时,根据进程的大小动态地建立分区,并使分区的大小正好适合进程的需要。因此系统分区的大小和数目是可变的。
动态分区分配没有内部碎片,但是有外部碎片。
- 内部碎片,分配给某进程的内存区域中,如果有些部分没有用上。
- 外部碎片,是指内存中的某些空闲分区由于太小而难以利用。
如果内存中空闲空间的总和本来可以满足某进程的要求,但由于进程需要的是一整块连续的内存空间,因此这些“碎片”不能满足进程的需求。可以通过紧凑技术来解决外部碎片(即改变内存空间的位置使其紧凑)。
把一个新作业装入内存时,须按照一定的动态分区分配算法,从空闲分区表(或空闲分区链)中选出一个分区分配给该作业。
对空间的回收操作也有以下四种情况:
四、非连续分配管理方式
基本分页存储管理方式
考虑上文中两种分配方式的缺点。固定分区分配,缺乏灵活性,会产生大量的内部碎片,内存的利用率很低。动态会产生很多外部碎片,虽然可以用紧凑技术来处理,但时间代价很高。
所以可以将固定分区分配改造为非连续分配。
分页存储基本概念
逻辑地址决定了虚拟内存可以有多大。如果是以十进制表示。则有以下。
页号=逻辑地址/页面长度(取除法的整数部分)
页内偏移量=逻辑地址%页面长度(取除法的余数部分)
实现地址转换
基本地址变化机构
基本地址变换机构可以借助进程的页表将逻辑地址转换为物理地址。
通常会在系统中设置一个页表寄存器(PTR),存放页表在内存中的起始地址F和页表长度M。进程未执行时,页表的始址和页表长度放在进程控制块(PCB)中,当进程被调度时,操作系统内核会把它们放到页表寄存器中。
设页面大小为L,逻辑地址A到物理地址E的变换过程如下:
具有快表的地址变化机构
由以上可知,存取一个数据或一个指令至少要访问两次内存。为此,在地址变换机构中增设一个具有并行查找能力的高速缓冲器——快表。
快表命中只需要访存一次。快表的有效性基于局部性原理。
两级页表
问题二可以使用虚拟内存实现,若想访问的页面不在内存中,则产生缺页中断(内中断),然后将目标页面从外存调入内存。
基本分段存储管理方式
概念和管理方式
分页和分段对比
段页式管理方式
五、虚拟内存管理
传统存储管理方式的特征、缺点
一次性:作业必须一次性全部装入内存后才能开始运行。作业很大时,不能全部装入内存,导致大作业无法运行。当大量作业要求运行时,由于内存无法容纳所有作业,只有少量作业可以运行,导致多道程序并发度下降。
驻留性:一旦作业被装入内存,就会一直驻留在内存中,直至作业运行结束。事实上,在一个时间段内,只需要访问作业的一小部分数据即可正常运行,这就导致了内存中会驻留大量的、暂时用不到的数据,浪费了宝贵的内存资源。
基本概念
虚拟内存有以下三个特征:
- 多次性 : 无需在作业运行时一次性全部装入内存,而是允许被分成多次调入内存。
- 对换性 : 在作业运行时无需一直常驻内存,而是允许在作业运行过程中,将作业换入、换出。
- 虚拟性 : 从逻辑上扩充了内存的容量,使用户看到的内存容量,远大于实际的容量。
请求分页管理方式
缺页中断是因为当前执行的指令想要访问的目标页面未调入内存而产生的,因此属于内中断。一条指令在执行期间,可能产生多次缺页中断。(如: copy A to B,即将逻辑地址A中的数据复制到逻辑地址B,而A、B属于不同的页面,则有可能产生两次中断)
在具有快表机构的请求分页系统中,访问一个逻辑地址时,若发生缺页,则地址变换步骤是 :查快表(未命中)—―查慢表(发现未调入内存)—―调页(调入的页面对应的表项会直接加入快表)――查快表(命中)――访问目标内存单元
补充细节:
- 只有“写指令”才需要修改“修改位”。并且,一般来说只需修改快表中的数据,只有要将快表项删除时才需要写回内存中的慢表。这样可以减少访存次数。
- 和普通的中断处理一样,缺页中断处理依然需要保留cPU现场。
- 页面调入内存后,需要修改慢表,同时也需要将表项复制到快表中。
页面置换算法
最佳置换算法(OPT)
最佳置换算法可以保证最低的缺页率,但实际上,只有在进程执行的过程中才能知道接下来会访问到的是哪个页面。操作系统无法提前预判页面访问序列。因此,最佳置换算法是无法实现的。
先进先出置换算法(FIFO)
当分配的内存块数量增加时,会出现异常。
最近最久未使用置换算法(LRU)
时钟置换算法(CLOCK)
改进型时钟置换算法
页面分配策略
驻留集大小
调入页面时机
预调页策略 : 根据局部性原理,一次调入若干个相邻的页面可能比一次调入果提前调入的页面中大多数都没被访问过,则又是低效的。因此可以预测不久之后可能访问到的页面,将它们预先调入内存。
但目前预测成功率只有50%,故这种策略用于进程的首次调入。由程序员决定调入哪些部分。
请求调页策略 : 进程在运行期间发现缺页时才将所缺页面调入内存。由这种策略调入的页面一定会被访问到,但由于每次只能调入一页,而每次调页都要磁盘I/O操作,因此I/O开销较大。
从何处调入页面
抖动
刚刚换出的页面马上又要换入内存,刚刚换入的页面马上又要换出外存,这种频繁的页面调度行为称为抖动,或颠簸。
产生抖动的主要原因是进程频繁访问的页面数目高于可用的物理块数(分配给进程的物理块不够)。
标签:操作系统,管理,装入,调入,地址,内存,进程,页面 来源: https://blog.csdn.net/weixin_45605341/article/details/113826565