内存:即内存条,也称主存储器(简称主存),用于存放数据。
为了缓和CPU和外存(磁盘)的速度矛盾,外存的程序先放入内存才能被CPU处理。
内存地址从0开始,每个内存地址对应一个存储单元。
存储单元的大小依据计算机的编址(按字节编址,则一个存储单元大小是1个字节;按字编址,32位计算机的一个存储单元大小是一个字即32位即4个字节,64位计算机中一个存储单元大小是一个字即64位即8个字节)。
内存的分配:程序装入内存时,为进程分配内存空间,并记录内存分配情况(内存分配表)。
内存的回收:程序撤销或者主动归还内存资源时,收回进程占用的内存空间,并修改内存分配表。
内部碎片:内存中,已经分配给了进程,但没用上的那部分区域。
外部碎片:内存中,部分空闲区域太小,难以分配给进程。
(1-1)单一连续分配:内存的用户区只能给一道用户程序。适用于早期的单道程序系统。
内存分为系统区(存放操作系统相关的数据)和用户区(用户进程相关数据)。
采用栅栏寄存器(存放系统区和用户区的界限地址)进行内存保护,避免用户访问或修改系统区。
实现简单,没有外部碎片,但只能一道程序,内存利用率低,产生内部碎片。
(1-2)固定分区分配: 内存的用户区分成固定大小的分区(分区大小相等或者分区大小不等)。适用于多道程序。需要分区说明表(数据结构)记录各个分区的分配和回收情况,通常按分区大小排列。
实现简单,无外部碎片;但有内部碎片,内存利用率低,若所有分区都无法满足大程序,用覆盖技术解决,将降低性能。(分区大小相等)缺少灵活性,不利于大程序;(分区大小不等)增加了灵活性,满足不同大小的进程需求。
(1-3)动态分区分配(可变分区分配):在进程装入内存时,根据进程大小动态建立分区。适用于多道程序。需要空闲分区表/空闲分区链(数据结构)记录各个空闲分区。需要一定的算法动态安排分配。回收分区时需注意合并分区。
没有内部碎片,但有外部碎片。但可用“拼凑”技术解决。(“拼凑”技术即紧凑技术:若各空闲内存空间都不够分配给进程,但总和超过进程大小,将分配给各进程的空间挪到一起,将零碎的空闲空间拼凑成一个大的连续的空闲空间)
首次适应算法 (First Fit) | 最佳适应算法 (Best Fit) | 最坏适应算法 (Worst Fit) | 邻近适应算法 (Next Fit) |
---|---|---|---|
分区排序: 按地址递增 | 分区排序: 按容量递增 | 分区排序: 按容量递减 | 分区排序: 按地址递增 |
从头开始查找, 从第一个大小适合的分区分配 | 优先从大小最适合的分区分配 | 优先从容量最大的分区分配 | 从上次查找结束位置开始, 从第一个大小适合的分区分配 |
综合看性能最好。算法开销小(不需重新排序) | 大分区容易被保留下来。但容易有外部碎片,算法开销大(需按容量重新排序) | 减少难以利用的小碎片。但不利于大进程,算法开销大(需按容量重新排序) | 算法开销小(不需重新排序)。但可能会使高地址的大分区也被用完 |
动态分区分配的回收分区:
- 回收区的前后没有空闲分区:空闲分区表/空闲分区链中,添加表项/节点。
- 回收区的前或后有空闲分区:空闲分区表/空闲分区链中,修改对应的表项/节点。
- 回收区的前后都有空闲分区:空闲分区表/空闲分区链中,合并对应的表项/节点(删除一个表项/节点,并修改对应的表项/节点)。
(2-1)分页存储管理:
页表(又称慢表):【数据结构】
- 在内存中,通常存放在系统区的进程控制块(PCB)中。
- 记录进程的页面与实际存放的内存块的映射关系(包括页号,内存中的页框号等)。
- 一个进程对应一张页表。一个页面对应一个页表项。页号从0开始。
- 页表的页表项是连续存放的,因此页号可隐含(即不记录页号,不占存储空间)。
页表太大时,采用多级页表机制:
一个页面对应一个页表项,将页面分组,使用多个页表。内存中一个页框存放一个页表(页表长度 = 页框大小 / 页表项长度)。
例如:两级页表
- 二级页表(若干个):记录页面在内存的地址。
- 页目录表(又称外层页表/顶层页表,一个):所有二级页表的目录。记录二级页表在内存的地址。
(若使用虚拟存储技术,页目录表在内存,其他页表在外存中需要时才调入内存。各级页表中还将记录是否在内存、在外存的地址等信息)
地址转换机构:
页表寄存器(PTR):
存放 页表在内存中的起始地址F 和 页表长度M。
- 进程未执行前,页表在内存中的起始地址和页表长度是存放在进程控制块(PCB)中。
- 进程被调度时,操作系统内核才将页表在内存中的起始地址和页表长度放入页表寄存器中。
页表长度用于判断逻辑地址中的页号是否越界(若页号页表长度,则页号越界)。
快表(又称联想寄存器):
- 英文缩写TLB,Translation Lookaside Buffer。
- 在CPU中。访问速度比内存中的页表(慢表)快。
- 存放最近访问过的页表项的副本。(即存放页表的部分副本)
逻辑地址 到 物理地址 的转换:
逻辑地址(又称虚拟地址/相对地址):程序员视角的地址。
物理地址(又称绝对地址):实际在内存中的地址。
页号 = 逻辑地址 / 页面大小 【除法取整数部分】
页内偏移量(又称页内地址) = 逻辑地址 % 页面大小 【除法取余数部分】
若逻辑地址是二进制表示,且页面大小是2的整数幂(例如:),则:
页内偏移量为逻辑地址的末尾k位。逻辑地址的其他二进制位为页号。
页表的起始地址:进程执行前,在PCB中;进程执行时,在页表寄存器中。
页表中页面对应页表项的起始地址:页表的起始地址 + 页号 * 页表项长度
页面在内存中的起始地址:页框号 * 页框大小
实际的物理地址:页面在内存中的起始地址 + 页面偏移量
地址转换过程:
(2-2)分段存储管理
段表:
- 在内存中。记录进程的段号、段长、段在内存中的起始地址(即段基址)等。
- 一个段表项对应一个段,段表中有多少段表项就表示进程有多少段。
- 每个段表项长度相同,段表项连续存放,段号可隐含(即不占存储空间)。
段表的起始地址:进程执行前,在PCB中;进程执行时,在页表寄存器中。
段表中段对应段表项的存放地址:段表起始地址+段号*段表项长度
段在内存中的起始地址:对应段表项中的段基址
实际的物理地址:段在内存中的起始地址+段内地址
用户需提供段名和段内地址。编译程序会把段名转换为段号。
逻辑地址可拆分为段号和段内地址。段号的位数代表进程最多分多少段;段内地址的位数代表段长最大是多少。
地址转换过程:
分页存储管理和分段存储管理的区别:
分页存储管理 | 分段存储管理 |
---|---|
以页框为单位为进程分配内存空间 | 以段为单位为进程分配内存空间 |
页框大小相同 | 段长不同 |
页表记录页号、在内存中的页框号 | 段表记录段号、段长、在内存中的起始地址 |
用户只需提供助记符 即分页的地址空间是一维的。 | 用户需提供段名和段内地址 即分段的地址空间是二维的。 |
页是信息的物理单位。 分页由系统完成,对用户不可见 | 段是信息的逻辑单位。 分段对用户可见,用户显示给出段名 |
提高内存的空间利用率。 不会产生外部碎片,会产生少量内部碎片。 | 方便用户编程,方便信息共享和保护。会产生外部碎片。 注:只有纯代码/可重入代码可以共享(纯代码/可重入代码:不能修改的信息。不属于临界资源) |
(2-3)段页式存储管理(分段和分页的结合)
用户提供段名和段内地址,编译程序将段名转换为段号,系统将段内地址转化为页号和页内偏移量。
逻辑地址可拆分成:段号、页号、页内偏移量(又称页内地址)。段号的位数表示进程最多分多少段,页号的位数表示每个段最多有多少页面,页内偏移量的位数表示页面大小是多少或内存的页框大小是多少。
地址转换过程:
(以请求分页存储管理为例)
在离散分配的基础上,物理上内存容量不变,逻辑上通过外存进行了扩充,使用户感觉内存容量比实际的大很多,就是虚拟内存。
传统存储的特征:一次性,驻留性。即程序一次性调入内存,并常驻内存,直到运行结束。
虚拟内存的特征:多次性,对换性,虚拟性。即程序存放在外存中,程序装入时,很快使用的页面先调入内存。程序运行时,用到的页面再调入内存;若内存空闲空间不够,通过一定置换算法,先将暂时用不到的页面从内存调出到外存,再将需要的页面调入内存。
虚拟内存需具备请求调页和页面置换功能。即需要的页面调入内存,空间不够时,不需要的页面调出到外存。
虚拟内存基于局部性原理。时间局部性:现在访问的信息将来可能仍访问。空间局部性:现在访问的信息附近的将来可能被访问。
地址转换过程:
传统存储管理 | 虚拟内存 |
---|---|
页表包括页号、在内存的地址。 | 页表包括页号、在内存中的地址、状态位(是否在内存)、访问字段(最近访问几次或上次访问时间,用于页面置换做参考)、修改位(调入内存后是否修改)、在外存中的地址。 |
无 | 需要缺页中断机构(需判断页面是否已在内存,若不在,则发生缺页中断,系统将页面从外存调入内存,有可能需要页面置换)。 缺页中断属于内中断。一条指令可能多次缺页中断。 |
无 | 页表项需要通过状态位检查页面是否在内存中; 若页面不在内存,需要请求调页; 若内存空间不够,需根据一定算法进行页面置换(将某页面从内存调出到外存,需要的页面调入内存); 页面调入内存后,需修改页表项,并将页表项复制到快表中。 |
页面分配策略:
驻留集:操作系统为进程分配的内存块的集合。
抖动/颠簸:分配的内存空间太小或者页面置换算法设计不当,会导致页面频繁调入调出。
工作集:某时间间隔里,进程实际被访问页面的集合。驻留集大小一般不能小于工作集大小。
页面分配、置换策略:
何时调入页面:
从何处调入页面:
在外存和内存之间调入调出,需要启动I/O操作,将产生一定的系统开销。
缺页率 = 访问的页面不在内存的次数 / 访问页面总次数
为获取更大的虚拟地址空间,除了磁盘(硬盘),还会扩展到固态硬盘,甚至网络硬盘。
参考:虚拟存储
虚拟存储技术是内存容量扩充的一种方式。
多道程序时,内存中存放多个进程,各个进程必须只能访问各自的内存区域,确保不会越界访问。
即本进程的内存区域:可读可写;非本进程的内存区域:不可读写;共享的内存区域:根据授权。
链接方式:静态链接、装入时动态链接、运行时动态链接。
装入方式:绝对装入、可重定位装入(又称静态重定位)、动态运行时装入(又称动态重定位)。
程序放入内存运行时,系统会建立相应的进程。进程在内存中包括两部分:程序段(存放指令等)和数据段(存放变量等)。