三、内存管理
文章目录
- 三、内存管理
- 内存基础知识
- 1.分类
- 1.1按在计算机中的作用(层次)
- 1.2按存储介质
- 1.3按存取方式
- 1.4按信息的可更改性
- 1.5按信息的可保存性
- 2.存储器的性能指标
- 六、存储器管理(内存管理基础)
- 0.内存保护
- 1.程序到程序运行(地址转换)
- 1.1编译
- 1.2链接
- 1.2.1静态链接
- 1.2.2装入时动态链接
- 1.2.3运行时动态链接
- 1.3装入
- 1.3.1绝对装入
- 1.3.2静态重定位装入
- ❗1.3.3动态重定位装入
- 2.内存扩充
- 2.1覆盖
- 2.2对换(交换)
- 2.3交换、覆盖的区别
- ❗3.分配与回收
- 3.1==连续==分配存储管理方式
- 3.1.1单一连续分配
- 3.1.2固定分区分配
- 3.1.3动态分区分配
- ❗==动态分区分配算法==
- 3.1.4紧凑技术
- 3.2==非连续==分配存储管理方式
- ❗3.2.1分页存储管理
- ❗逻辑地址结构
- 页表
- 基本==地址变换机构==
- ==快表TLB==地址变换机构
- ❗二级页表
- 3.2.2分段存储管理
- 地址结构
- 段表
- 地址变换
- 分段vs分页管理
- 3.2.3段页式存储管理
- 地址转换
内存基础知识
详见 计算机组成原理 3.存储系统
1.分类
1.1按在计算机中的作用(层次)
-
高速缓冲存储器
简称Cache,位于主存和CPU之间,用来存放正在执行的程序段和数据,以便CPU能高速地使用它们。Cache的存取速度可与CPU的速度相匹配,但存储容量小、价格高。目前的高档计算机通常将它们制作在CPU中。
-
主存储器
简称主存,又称内存储器(内存),用来存放计算机运行期间所需的大量程序和数据,CPU可直接随机地对其进行访问,也可以和高速缓冲存储器(Cache)及辅助存储器交换数据。其特点是容量较小、存取速度较快、每位价格较高。
-
辅助存储器
简称辅存,又称外存储器(外存),是主存的后援存储器,用来存放当前暂时不用的程序和数据,以及一些需要永久性保存的信息,它不能与CPU直接交换信息。其特点是容量极大、存取速度较慢、单位成本低。
1.2按存储介质
- 磁表面存储器(外存硬盘,磁盘、磁带)、磁心存储器,
- 半导体存储器(RAM,ROM,cache、MOS型存储器、双极型存储器),
- 光存储器(光盘)。
1.3按存取方式
-
随机存储器(RAM,random access memory)
存储器的任何一个存储单元的内容都可以随机存取,而且存取时间与存储单元的物理位置无关。
主要用作主存或高速缓冲存储器。
RAM又分为:
- 静态RAM(SRAM以触发器原理寄存信息);
- 动态RAM(DRAM以电容充电原理寄存信息)。
-
顺序存取存储器(SAM,sequential access memory)
顺序存取存储器的内容只能按某种顺序存取,读写一个存储单元所需时间取决于存储单元所在的物理位置。
如磁带。
-
直接存取存储器(DAM,direct access memory)
既有随机存取特性,也有顺序存取特性。存取信息时通常先寻找整个存储器中的某个小区域(如磁盘上的磁道),再在小区域内顺序方式查找。
如机械硬盘。
速度:RAM>DAM>SAM
以上的都是串行访问存储器。
- 串行访问存储器
对存储单元进行读写操作时,需按其物理位置的先后顺序寻址,包括顺序存取存储器SAM(如磁带)与直接存取存储器DAM(如磁盘)。
- 相联存储器(Associative Memory),即可以按内容访问的在储器(CAM,ContentAddressed Mamory)可以按照内容检索到存楮位置进行读写,“快表”就是一种相联存储器。
1.4按信息的可更改性
- 读写存储器(Read/Write Memory)
即可读、也可写。
如:磁盘、RAM,Cache。
- 只读存储器(ROM,Read Only Memory)
只能读,不能写。信息一旦写入存储器就固定不变,即使断电,内容也不会丢失。
通常用它存放固定不变的程序、常数和汉字字库,甚至用于OS的固化。它与随机存储器可共同作为主存的一部分,统一构成主存的地址域。
如:实体音乐专辑通常采用CD-ROM,实体电影采用蓝光光碟,BIOS通常写在ROM中。
由ROM派生出的存储器也包含可反复重写的类型,广义上的ROM已可通过电擦等方式进行写入,但其写入速度比读取速度慢得多。
1.5按信息的可保存性
- 易失性存储器
断电后,存储信息即消失的存储器,称为易失性存储器(RAM,即主存、cache)。
- 非易失性存储器
断电后信息仍然保持的存储器,称为非易失性存(ROM,磁表面存储器、光存储器)。
- 破坏性读出
若某个存储单元所存储的信息被读出时,原存储信息被破坏,则称为破坏性读出(如DRAM芯片,读出数据之后要重写)。
具有破坏性读出性能的存储器,每次读出操作后,必须紧接一个再生的操作,以便恢复被破坏的信息。
- 非破坏性读出
若读出时,被读单元原存储信息不被破坏,则称为非破坏性读出(如SRAM芯片,ROM,磁盘,光盘)。
2.存储器的性能指标
通常把存放一个二进制位的物理器件称为存储元,它是存储器的最基本的构件。地址码相同的多个存储元构成一个存储单元。若干存储单元的集合构成存储体。当对某个基本单元电路进行读/写操作时,必须被行、列地址共同选中。
存储器有3个主要性能指标,即存储容量、单位成本、存储速度。
位:比特bit(0/1)
字节byte, 就是简写为b:1Byte = 8Bit
1KB =210B
8KB =210 * 23 = 213B
1MB =210 KB = 220B
-
存储容量
存储容量 = 存储单元个数 × 存储字长 如: 1 M × 8 位 存储容量=存储单元个数×存储字长\\ 如:1M × 8位 存储容量=存储单元个数×存储字长如:1M×8位
MDR位数反应 存储字长。 -
单位成本(每位价格)
每位价格 = 总成本 总容量 每位价格=\frac{总成本}{总容量} 每位价格=总容量总成本 -
存储速度(数据传输率,主存带宽)
数据传输率 = 数据的宽度 存储周期 存储周期 = 存取时间 + 恢复时间 数据传输率=\frac{数据的宽度}{存储周期}\\ 存储周期=存取时间+恢复时间 数据传输率=存储周期数据的宽度存储周期=存取时间+恢复时间- 存取时间(Ta):存取时间又称存储器的访问时间(Memory Access Time),是指从启动一次存储器操作到完成该操作所经历的时间,分为读出时间和写入时间。(读出时间是指从主存接收到有效地址开始到数据稳定为止的时间,写入时间是指从主存接收到有效地址开始到数据写入被写单元为止的时间)
- 存取周期(Tm):存取周期又称读写周期或访问周期。它是指存储器进行一次完整的读写操作所需的全部时间,即连续两次独立访问存储器操作(读或写操作)之间所需的最小时间间隔 (存取周期=存取时间+恢复时间)
- 主存带宽(Bm):主存带宽又称数据传输率,表示每秒从主存进出信息的最大数量,单位为字/秒、字节/秒(B/s)、位/秒(b/s)。
存取时间不等于存储周期,通常存储周期大于存取时间。这是因为对任何一种存储器,在读写操作之后,总要有一段恢复内部状态的复原时间。对于破坏性读出的存储器,存取周期往往比存取时间大得多,因为存储器中的信息读出后需要马上进行再生。
六、存储器管理(内存管理基础)
内存管理是指软件运行时对计算机内存资源的分配和使用的技术。其最主要的目的是如何高效,快速的分配,并且在适当的时候释放和回收内存资源。
操作系统的工作(5种):
-
内存空间的分配与回收(主要)
- 连续分配存储管理方式
- 单一连续分配
- 固定分区分配
- 动态分区分配
- 非连续分配存储管理方式
- 分页存储管理
- 分段存储管理
- 段页式存储管理
- 连续分配存储管理方式
-
提供某种技术从逻辑上对内存空间进行扩充
- 覆盖overlay
- 对换swapping
- 虚拟存储
-
地址转换。逻辑->物理
为使编程更方便,程序员写程序时应该只需要关注指令、数据的逻辑地址。而逻辑地址到物理地址的转换(这个过程称为地址重定位)应该由操作系统负责,这样就保证了程序员写程序时不需要关注物理内存的实际情况。
- 链接:
- 静态链接
- 装入时动态链接
- 运行时动态链接
- 装入:
- 绝对装入
- 静态重定位装入
- 动态重定位装入
- 链接:
-
内存共享。多个进程访问内存共享区的同一部分。
-
内存保护。保证各进程在各自的存储空间运行,互不干扰。
0.内存保护
内存保护需要由操作系统、硬件机构合作,保证进程空间不被非法访问(越界)。可采取2种方法:
- 方法一:在CPU中设置一对上、下限寄存器,存放进程的上、下限地址。进程的指令要访问某个地址时,CPU检查是否越界。
- 方法二:采用重定位寄存器(又称基址寄存器)和界地址寄存器(又称限长寄存器)进行越界检查。
- 重定位寄存器中存放的是进程的起始物理地址。
- 界地址寄存器中存放的是进程的最大逻辑地址。
1.程序到程序运行(地址转换)
三步:
- 编译
- 链接
- 装入
1.1编译
把高级语言编译为机器语言。
1.2链接
1.2.1静态链接
在程序运行之前把各个目标模块和它们所需要的库函数,链接成一个完成的可执行文件(载入模块),之后不可拆开。
1.2.2装入时动态链接
各目标模块装入内存时,运行前,边装入边链接。
1.2.3运行时动态链接
需要运行哪一个目标模块时,才把哪一个放到装入模块。
1.3装入
逻辑地址(logic address)、相对地址:CPU生成的地址。
物理地址(physical address)、绝对地址:内存单元看到的地址,就是装入内存地址寄存器的地址。
逻辑地址的地址参数会转换成物理地址,比如0变成n。
1.3.1绝对装入
absolute loading mode。
在编译的时候,就知道程序将放到内存的哪个位置。那么编译产生的就是物理地址的代码。装入程序按照装入模块中的地址,将程序和数据装入内存。
就是装入模块(*.exe)0~179,现在就采用n~n+179。
缺点:灵活性低。只适用于单道程序环境。(那时候还没有操作系统)
1.3.2静态重定位装入
可重定位装入,relocation loading mode。又称静态重定位。
编译、链接后的装入模块的地址都是从0开始的,指令中使用的地址、数据存放的地址都是相对于起始地址而言的逻辑地址。可根据内存的当前情况,将装入模块装入到内存的适当位置。装入时对地址进行“重定位”,将逻辑地址变换为物理地址(地址变换是在装入时一次完成的)。
【总结】装入程序根据内存的具体情况,对装入模块的地址进行 +n 的操作。
用于早期多道批处理操作系统。
特点:
- **在一个作业装入内存时,必须分配其要求的全部内存空间(一定是连续的)。**如果没有足够的内存,就不能装入该作业;
- 作业一旦进入内存后,在运行期间就不能再移动,也不能再申请内存空间。
❗1.3.3动态重定位装入
动态运行时装入,dynamic run-time loading mode。又称动态重定位。
编译、链接后的装入模块的地址都是从0开始的。装入程序把装入模块装入内存后,并不会立即把逻辑地址转换为物理地址,而是把地址转换推迟到程序真正要执行时才进行。因此装入内存后所有的地址依然是逻辑地址。
这个方式有一个重定位寄存器(存放装入模块的起始位置地址)。
【注意】重定位寄存器,使得允许程序在内存中移动,整个系统中只有一个重定位寄存器。每次切换进程,都需要保存、恢复该寄存器的值。
【总结】装入模块存入内存的仍然是逻辑地址,地址转换在程序真正要运行的时候才进行。
物理地址 = 逻辑地址 + 重定位寄存器的地址。
特点:
- 允许程序在内存中发生移动,因为重定位寄存器的内容可以更改。
- 并且可将程序分配到不连续的存储区中;
- 在程序运行前只需装入它的部分代码即可投入运行,然后在程序运行期间,根据需要动态申请分配内存;
- 便于程序段的共享,可以向用户提供一个比存储空间大得多的地址空间。
- 动态重定位需要用到地址变换机构。
2.内存扩充
2.1覆盖
覆盖技术,解决“程序大小超过物理内存总和”的问题。用于早期操作系统,现在不常用。
内存中有固定区、覆盖区。
把程序分成多个段(多个模块),常用的段常驻内存“固定区”,调入后就不再调出(除非运行结束);不常用的段在需要的时候调入内存“覆盖区”,需要用到时调入内存,用不到时调出内存。
要求:程序员提供一个清楚的覆盖结构。即程序员必须把一个程序划分成不同的程序段,并规定好它们的执行和覆盖顺序。
由程序员声明覆盖结构,操作系统完成自动覆盖。
缺点:对用户不透明,增加了用户编程负担。
【详解】计算机术语“透明”是什么意思?“对…是透明的”怎样理解?_透明是可见还是不可见
覆盖技术只用于早期的操作系统中,现在已成为历史。
2.2对换(交换)
用**中级调度(内存调度)**实现。
对象是进程,等待状态的进程驻留内存会造成存储空间的浪费。因此,有必要把处于等待状态的进程换出内存。
暂时换出外存等待的进程状态为挂起状态(挂起态,suspend)。挂起态又可以进一步细分为就绪挂起、阻塞挂起两种状态。
交换技术是实现此目标的常用方法之一。(进程在内存与磁盘间动态调度)
【注意】PCB常驻内存,不会被换到外存。
- 离散分配方式:提高空间利用率
- 连续分配方式:对换区的I/O速度比文件区快。
优点:与覆盖技术相比,交换技术不要求程序员给出程序段之间的覆盖结构。
- 应该在外存(磁盘)的什么位置保存被换出的进程?
具有对换功能的操作系统中,通常把磁盘空间分为文件区和对换区两部分。
文件区主要用于存放文件,主要追求存储空间的利用率,因此对文件区空间的管理采用离散分配方式。
对换区空间只占磁盘空间的小部分,被换出的进程数据就存放在对换区。由于对换的速度直接影响到系统的整体速度,因此对换区空间的管理主要追求换入换出速度,因此通常对换区采用连续分配方式(学过文件管理章节后即可理解)。总之,对换区的I/O速度比文件区的更快。
- 什么时候应该交换?
交换通常在许多进程运行且内存吃紧时进行,而系统负荷降低就暂停。
例如:在发现许多进程运行时经常发生缺页,就说明内存紧张,此时可以换出一些进程;如果缺页率明显下降,就可以暂停换出。
- 应该换出哪些进程?
可优先换出阻塞进程;
可换出优先级低的进程,为了防止优先级低的进程在被调入内存后很快又被换出,有的系统还会考虑进程在内存的驻留时间…
2.3交换、覆盖的区别
1.交换主要在不同进程或作业之间进行。
2.覆盖主要在同一个进程或作业内进行,只能对与覆盖程序段无关的程序段进行覆盖。
❗3.分配与回收
【注意】操作系统实现“分区”存储管理的代价最小。(不是分页、分段)
3.1连续分配存储管理方式
连续分配:系统为用户分配的是一个连续的内存空间。
内部碎片:分配给进程的内存区中,有部分没有用上,分多了。
外部碎片:内存中的某些空间因为太小而难以利用。
3.1.1单一连续分配
单道程序环境,内存分为系统区、用户区。
内存中只能有一道用户程序。即使用户区有很多空闲,但是只能进行一个进程。
优点:实现简单;无外部碎片;可以采用覆盖技术扩充内存;不一定需要采取内存保护(eg:早期的PC操作系统MS-DOS) 。
缺点:只用于单用户、单任务;有内部碎片;存储器利用率低。
3.1.2固定分区分配
多道程序环境,内存分为系统区、用户区,用户区划分为若干固定大小(可以相等、也可以不相等)的分区,每个分区只装入一道作业。
优点:实现简单;无外部碎片。
缺点:若程序太大,所有的分区都无法满足需求,就不得不使用覆盖技术(但是很适合用于一台计算机控制多个相同的对象的场合);有内部碎片;存储器利用率低。
操作系统需要建立一个数据结构:分区说明表,来实现各个分区的分配与回收。每个表项对应一个分区,通常按分区大小排列。每个表项包括对应分区的大小、起始地址、状态(是否已分配)。
分区说明表:
分区号 | 大小 | 起始地址 | 状态 |
---|---|---|---|
1 | 12 | 20 | 已分配 |
2 | 32 | 32 | 空闲 |
3 | 64 | 64 | 空闲 |
4 | 128 | 128 | 空闲 |
3.1.3动态分区分配
可变分区分配,他不会预先划分内存分区。而是在进程装入内存时,根据进程的大小动态建立分区。并使分区的大小正好适合进程的需要。内此系统分区的大小、数目是可变的。
采用了动态重定位装入,所以需要硬件地址变换机构。
- 系统要用什么样的数据结构记录内存的使用情况?
数据结构:
-
空闲分区表:与固定分区分配一样
-
空闲分区链
- 当有多个空闲分区满足时,如何选择分区?
按照动态分区分配算法。
❗动态分区分配算法
- 首次适应算法(效果最好)
first fit,FF
空闲分区按照地址递增顺序排列。每次都是从低地址开始查找,找到第一个能满足大小空闲的分区(表或链)。
- 最佳适应算法
best fit,BF
空闲分区按照容量递增顺序排列。每次都是从最小分区开始查找,找到第一个能满足大小空闲的分区。
缺点:因为每次都是选用的最小分区,所以每次都会剩下更小,更难利用的分区,产生外部碎片。
【2019年408真题】最佳适应算法最容易产生内部碎片。
- 最坏适应算法
worst fit,WF。最大适应算法(Largest Fit)
空闲分区按照容量递减顺序排列。每次都是从最大分区开始查找,找到第一个能满足大小空闲的分区。
缺点:不断分割大分区,之后的大进程来了,可能没有分区来使用。
- 邻近适应算法
next fit,NF
空闲分区按照地址递增顺序排列(例如形成一个循环链表)。每次从上次检查结束的位置开始查找,找到第一个能满足大小空闲的分区。
分区回收:4种情况
3.1.4紧凑技术
无内部碎片,有外部碎片。
可以通过紧凑技术来解决外部碎片的问题。
对进程进行挪位,让进程更紧凑,把小空间变大。
3.2非连续分配存储管理方式
可以把进程拆分成多段进行存储,所以分区越小,产生的空闲分区(碎片)就更小。
❗3.2.1分页存储管理
将内存空间分为大小相等的分区,每个分区称为页框(frame)(页框 = 页帧 = 内存块 = 物理块 = 物理页面)。每个页框有一个编号,称为页框号(页框号 = 页帧号 = 内存块号 = 物理块号 = 物理页号),页框号从 0 开始,编号小的页框就在低地址位。
将进程的逻辑地址空间也分为与页框大小相等的一个个部分,每个部分称为一个“页”或“页面”。每个页面也有一个编号,即“页号”,页号也是从0开始。
操作系统以页框为单位为各个进程分配内存空间。
【注意】
- 主存的分配以页框为单位。
- 主存储器的访问,以字节、字为单位。
进程的每个页面分别放入一个页框中。也就是说,进程的页面与内存的页框有一一对应的关系(使用页表实现)。
各个页面不必连续存放,可以放到不相邻的各个页框中。
80是逻辑地址的位置,在50-99橙色页中。
50是已知的起始地址,它的重定位寄存器内是400,可以算出在内存中的物理起始地址是400+50=450
偏移量是80-50=30
实际物理地址是450+30=480
❗逻辑地址结构
图中地址长度一共32位,
主存最大容量为 232 B = 4G。
其中0~11位为页内地址(或页内偏移量),有12位,即每页(页框)的大小为212B = 4096B = 4KB。
12~31位为页号,即空间大小,最多允许有 220 = 1024K = 1M页。
P
=
i
n
t
[
A
L
]
(
页号
=
取整
[
逻辑地址
页面长度
]
)
W
=
[
A
]
m
o
d
L
(
页内偏移量
=
逻辑地址
%
页面长度(除法取余)
)
实际物理地址
=
页面在内存中的起始地址
+
页内偏移量
P=int[\frac{A}{L}] \ (页号=取整[\frac{逻辑地址}{页面长度}])\\[1cm] W=[A] mod\ L \ (页内偏移量=逻辑地址\%页面长度(除法取余)) \\ \\ 实际物理地址 = 页面在内存中的起始地址+页内偏移量
P=int[LA] (页号=取整[页面长度逻辑地址])W=[A]mod L (页内偏移量=逻辑地址%页面长度(除法取余))实际物理地址=页面在内存中的起始地址+页内偏移量
A
:逻辑地址
L
:页面长度
例如上面的例子:
页号 = 80/50 = 1
偏移量 = 80%50 = 30而1号页的起始位置450
实际物理地址是450+30=480
- 在选择页面大小的时候,通常考虑下面的因素:
- 页面大:
- 好处:用于管理的页表少;
- 坏处:页内碎片会比较大。
- 页面小:和页面大好坏处正好相反。
最佳方案是通过计算,获得恰当好处的页面大小。
划分页面大小一般是根据内存大小确定的。为了方便计算机计算,页内偏移量、页面大小一般是2的整数幂。
页表
为了知道进程的每个页面在内存中存放的位置,操作系统为每个进程都建立一张表。
注:页表通常存在PCB(进程控制块)中。
【注意】查找页表的工作是由硬件实现的。
- 如何通过内存大小和页面大小,推算页表长度(内存块数量)?
Eg:假设某系统物理内存大小为4GB,页面大小为4KB,则每个**页表项(一个格子)**至少应该为多少字节?
- 内存块大小 = 页面大小 = 4KB = 212B(每个页框存储的大小)
- 4GB的内存总共会被分为232/212=220个内存块
- 内存块号的范围应该是0~220-1
- 内存块号至少要用20 bit来表示
- 至少要用3B来表示块号(3*8=24bit)
页表项是连续存放的,因此页号可以是隐含的,不占存储空间(类比数组的下标,0,1,2……)。
基本地址变换机构
基本地址变换机构,是用于实现逻辑地址到物理地址转换的一组硬件机构。
在系统中设置一个页表寄存器(page-table register,PTR),存放页表在内存中的起始地址 F、页表长度 M。平时不执行进程时,起始地址、页表长度存放在PCB中,当进程运行时,才会把这两者放到PTR中。
【注意】页面大小是2的整数幂。
解题步骤:
A
:逻辑地址
L
:页面长度
-
求出页号 P=A/L、页内偏移量W=A%L;
-
根据页号判断是否越位(越界);
比较页号P和页表长度M,若P ≥ M,则产生越界中断,否则继续执行。(【注意】页号是从0开的,而页表长度至少是1,因此P=M时也会越界)。
-
根据页号求出块号;
页表中页号P对应的页表项地址(页表的页号)= 页表起始地址F+页号P * 页表项长度,取出该页表项内容b,即为内存块号。(注意区分页表项长度、页表长度、页面大小的区别)
页表长度:页表中总共有几个页表项,即总共有几页。
页表项长度:页表项的大小。
页面大小:一个页面占多大的存储空间。偏移量占几位就是页面大小。 -
物理地址E:
E = 块号 b ∗ 页面长度 ( 页面大小 ) L + 页内偏移量 W E = 块号b * 页面长度(页面大小)L + 页内偏移量W E=块号b∗页面长度(页面大小)L+页内偏移量W
页面长度(页面大小)L的计算: 2 页内偏移量的位数 2^{页内偏移量的位数} 2页内偏移量的位数。
【注意】页式管理中地址是一维的。因为在实际中寻找物理地址,只需要用户给出逻辑地址,其他都可以计算出。
例1:
例2:若页面大小L为1K字节,页号2对应的内存块号b=8,将逻辑地址A=2500转换为物理地址E。
等价描述: 某系统按字节寻址,逻辑地址结构中,页内偏移量占10位,页号2对应的内存块号b=8,将逻辑地址A=2500转换为物理地址E。
这里 页内偏移量占10位 就是说明一个页面的大小为210B = 1KB
计算页号、页内偏移量
页号P=A/L = 2500/1024=2;页内偏移量W=A%L= 2500%1024= 452根据题中条件可知,页号2没有越界,其存放的内存块号b = 8
物理地址E= b*L+W = 8 * 1024+425= 8644
快表TLB地址变换机构
快表的依据是:局部性原理。
时间局部性:如果执行了程序中的某条指令,那么不久后这条指令很有可能再次执行;如果某个数据被访问过,不久之后该数据很可能再次被访问。(因为程序中存在大量的循环)
空间局部性:一旦程序访问了某个存储单元,在不久之后,其附近的存储单元也很有可能被访问。(因为很多数据在内存中都是连续存放的)
因为访问的都是这几个内存块,所以查询到页表项也是相同的,所以创建快表,减少访问页表的次数。
快表,又称联想寄存器(associative memory),在IBM系统中取名地址变换高速缓存(translation look aside buffer,TLB),是一种访问速度比内存快很多的高速缓冲存储器,用来存放最近访问的若干页表项,以加速地址变换的过程。与此对应,内存中的页表常称为慢表。
【考点】平均访存时间 = 命中率 × 快表访存 + 不命中率 × (快表访存+页表访存)+ 内存访存
❗二级页表
单级页表的问题:
- 页表的存储是连续的,如果特别大,那么它的存在本身就破坏了分页存储的优点。
- 根据局部性原理,不需要所有页表项一直都在,增加检索耗时,只需要几个特定的。
所以,把页表再分页存储,建立一个外层页表(outer page table)(或一级页表、页目录表、顶层页表)来存储页表(页表索引)的页表。套娃,所以后续也就有多级页表。
页目录号 | 页表索引(页号) | 页内偏移量 |
---|
【2021年408真题】在多级页表中,页表基址寄存器存放的都是顶级页表(一级页表)的起始物理地址。
【2015年408真题】有几位页目录号,就有几个页面:
页目录号(10位) | 页表索引(页号) | 页内偏移量 |
---|
那么就有210个页目录项 → 有210个页面,这个也就是页表占了多少页。
【注意事项】若采用多级页表机制,则各级页表大小不能超过一个页面。
【考点:计算多级页表】
例:某系统按字节编址,采用40位逻辑地址,页面大小为4KB,页表项大小为4B,假设采用纯页式存储,则要采用(3)级页表,页内偏移量为(12)位?
页面大小 = 4KB = 212B,按字节编址,因此页内偏移量为12位。
页号 = 40 - 12= 28位。
页面大小 = 212B,页表项(页里面的一个格子)大小= 4B,则每个页面可存放212 / 4 = 210个页表项。
28 / 10 = 2.8,两级页表不够,可以分三级。
因此各级页表最多包含210个页表项,需要10位二进制位才能映射到210个页表项,因此每一级的页表对应页号应为10位。总共28位的页号至少要分为三级。(两级页表不够,可以分更多级)
- 访存次数随之增加。
第一次访存:访问内存中的页目录表;
第二次访存:访问内存中的二级页表;
第三次访存:访问目标内存单元。
N级页表访问一个逻辑地址需要N+1次访存。
3.2.2分段存储管理
进程的地址空间:按照程序自身的逻辑关系划分为若干个段,每个段都有一个段名(在低级语言中,程序员使用段名来编程),每段从0开始编址。
由于是按逻辑功能模块划分,用户编程更方便,程序的可读性更高。
内存分配规则:以段为单位进行分配,每个段在内存中占据连续空间,但各段之间可以不相邻。
有点像动态分区分配,会产生外部碎片,但是不会产生内部碎片。
地址结构
段号的位数决定了每个进程最多可以分几个段。
段内地址位数决定了每个段的最大长度是多少。
在上述图中,若系统是按字节寻址的,则:
段号占16位,因此在该系统中,每个进程最多有216 = 64K个段
段内地址占16位,因此每个段的最大长度是216 = 64KB。
段表
段号就是逻辑地址的位置,基址是在内存中的位置。
因为每个段的长度不一定,所以用段长来表示段的段的长度(类似偏移)。而页表没有,因为页表的每一页都是一样大的。
段表项的大小是相同的。由于段表项长度相同,因此段号是可以隐藏的,不占存储空间。
【注意】段表地址、段表长度是存放在PCB中的。
地址变换
- 由逻辑地址得到段号、段内地址;
- 段号与段表寄存器中的段长度比较,检查是否越界;
- 由段表始址、段号找到对应段表项;
- 根据段表中记录的段长,检查段内地址是否越界;
- 由段表中的"基址+段内地址"得到最终的物理地址;
- 访问目标单元。
分段vs分页管理
分段、分页管理的对比
-
页是信息的物理单位。分页的主要目的是为了实现离散分配,提高内存利用率。分页仅仅是系统管理上的需要,完全是系统行为,对用户不可见的。
段是信息的逻辑单位。分段的主要目的是更好地满足用户需求。一个段通常包含着一组属于一个逻辑模块的信息。分段对用户是可见的,用户编程时需要显示地给出段名。
-
页的大小固定且由系统决定。
段的长度却不固定,决定于用户编写的程序。
-
分页的用户进程地址空间是一维的,程序员只需给出一个记忆符即可表示一个地址。
分段的用户进程地址空间是二维的,程序员在标记一个地址时,既要给出段名,也要给出段内地址。
-
分段比分页更容易实现信息的共享和保护。只需让各进程的段表项指向同一个段即可实现共享。不能被修改的代码称为纯代码或**可重入代码**(不属于临界资源),这样的代码可以共享的。可修改的代码是不能共享的。
目的不同:
- 分段:更好的满足用户的需求,实现程序模块化、保护。
- 分页:离散分配,提高内存利用率。
访问一个逻辑地址需要几次访存?
分页(单极页表):第一次访存——查内存中的页表,第二次访存——访问i目标内存单元。总共两次访存。
分段:第一次访存——查内存中的段表,第二次访存——访问目标内存单元。总共两次访存。
与分页系统类似,分段系统中也可引入分段快表机构,将近期访问过的段表项放到块表中,这样可以少一次访问,加快地址变换速度。
3.2.3段页式存储管理
先分段,再把大的段分页。
段号的位数决定了每个进程最多可以分几个段。
页号位数决定了每个段最大有多少页。
页内偏移量决定了页面大小、内存块大小是多少。
段页式需要访存3次,而分别的段式、页式都是2次。
在上述例子中,若系统是按字节寻址的,则:
段号占16位,因此在该系统中,每个进程最多有216= 64K个段。
页号占4位,因此每个段最多有24 = 16页。
页内偏移量占12位,因此每个页面/每个内存块大小为212 = 4096 = 4KB
“分段”对用户是可见的,程序员编程时需要显式地给出段号、段内地址。而将各段“分页”对用户是不可见的。系统会根据段内地址自动划分页号和页内偏移量。因此段页式管理的地址结构是二维的。
所以一个进程对应一个段表,但是可能会对应多个页表。
地址转换
优点:
保留了分段和请求分页存储管理的全部优点;
提供了虚存空间,能更有效利用主存。
缺点:
增加了硬件成本;
系统复杂度较大。