前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >非常详细!操作系统【内存管理】培训级教程

非常详细!操作系统【内存管理】培训级教程

原创
作者头像
曾高飞
发布2025-06-05 13:02:11
发布2025-06-05 13:02:11
1260
举报

1 内存管理基础概念

1.1 总览

image1
image1

1.2 内存管理应有的功能

1.2.1 内存空间的分配和回收

示意图:

image2
image2
1.2.2 从逻辑上扩充内存

试想,随便下载一个大软件,其大小远远超过我们的内存大小,那么为什么这个软件可以运行呢?原因是操作系统采用了虚拟内存,即使物理空间较小,但是逻辑空间却可以很大。

1.2.3 地址转换

提供地址转换功能,负责程序的逻辑地址与物理地址的转换

image3
image3

三种装入方式为:

image4
image4
1.2.4 内存保护

提供内存保护功能,保证各进程在各自存储空间内运行,互不干扰。

使进程只可以访问属于自己的空间,不能去访问系统内核、其他进程的内存空间。那么,如何才可以实现内存保护呢?

以下图的进程1为例子

image5
image5

(1)设置上下限寄存器。

image6
image6

例如,进程1的实际物理地址为100-279,那么下限寄存器应该存放100,上限寄存器应该存放279。

(2)重定位寄存器、界地址寄存器

image7
image7

重定位寄存器存放进程的实际物理地址的下限,界地址寄存器存放进程所需的最空间。例如,进程1的重定位寄存器存放100,界地址寄存器存放179-0=179。

1.3 知识总结

image8
image8

2 覆盖与交换

2.1 总览

image1
image1

2.2 覆盖技术

2.2.1 覆盖技术的基本思想
image2
image2
2.2.2 例子
image3
image3

如图,这是一个程序的结构调用图。可以看到,A是程序运行所必须的代码段,因此放在固定区内;B、C不可能同时运行,因此可以分配同一个覆盖区,D、E、F同理。如图所示

image4
image4

因此,本来应该将代码全部放入,但是操作系统只分配了一部分空间就实现了全部放入的结果,因此从逻辑上看,操作系统的内存大小是被拓展了的。

2.2.3 缺点
image5
image5

2.3 交换技术

2.3.1 基本思想
image6
image6

比如说,假设内存中有进程1、2、3,如图

image7
image7

此时内存紧张,进程1、2需要暂时换出外存,因此在内存保留它们的PCB后(方便操作系统的后续管理)将它们置于挂起队列,空出的内存空间给更为紧张的进程使用。

2.3.2 待解决的问题
image8
image8

对于问题1:

image9
image9

磁盘空间的示意图:

image10
image10

对于问题2:

image11
image11

对于问题三

image12
image12

2.4 总结

image13
image13

3 连续内存分配

3.1 总览

image1
image1

3.2 单一连续分配

3.2.1 思想
image2
image2

如图:

image3
image3
3.2.2 优点
image4
image4

一个进程独占内存,就不会发生进程访问其他进程的内存空间的情况,且即使进程访问了操作系统的内核程序,通常也可以通过重启解决,所以这种方式下不一定需要采取内存保护?

3.2.3 缺点
image5
image5

3.3 固定分区分配

3.3.1 基本思想
image6
image6
3.3.2 分类

根据分配的空间相等与否可以分为以下两类

image7
image7

如图

image8
image8
3.3.3 特点
image9
image9
3.3.4 如何管理固定分区

可以通过分区说明表进行管理,其具体内容如图:

image10
image10

这种数据结构可以通过数组或链表实现

image11
image11
3.3.5 优缺点
image12
image12

3.4 动态分区分配

3.4.1 基本思想
image13
image13
3.4.2 记录内存使用情况的数据结构

可以采取空闲分区表、空闲分区链表示

(1)空闲分区表

例子:

image14
image14
image15
image15

(2)空闲分区链

例子:

image16
image16
3.4.3 空闲分区的分配

分配算法在下一小节进行详细描述

image17
image17
3.4.4 分区的分配和回收

假设操作系统采用空闲分区表管理分区(使用空闲分区链同理)

(1)分配操作

假设起始表内容如下:

image18
image18

①假如一个空闲分区的大小大于进程申请的空间,那么直接修改内容和即可。 假设一个4MB的进程进入,需要分配到分区1中,那么分区表应该修改如下:

image19
image19

②假如一个空闲分区的大小等于进程申请的空间,那么需要删除该内容。假设一个4MB的进程进入,需要分配到分区3中,那么分区表应该修改如下:

image20
image20

(2)回收操作

①回收分区的后面(后面)有空闲分区

直接修改表项内容

image21
image21

②回收分区的后面没有空闲分区

增加一个表项内容

image22
image22

③回收分区的前后均为空闲分区

合并表项内容

image23
image23

注意:各表项的排序不一定按照分区地址的大小进行排序

4 基本分页存储管理的基本概念

4.1 总览

image1
image1

4.2 什么是分页存储

4.2.1 将物理空间分页
image2
image2
4.2.2 将逻辑空间分页
image3
image3

方便管理员进行管理

4.2.3 空间的分配
image4
image4
4.2.4 区分概念
image5
image5

4.3 页表

4.3.1 概述

(1) 必要性

image6
image6

(2) 示意图

image7
image7

(3) 注意

image8
image8
4.3.2 页表项的大小

(1)块号的字节

假设:

image9
image9

由于内存块的大小(物理)=页面大小(逻辑) = 4KB = 212B,则一个4GB的内存总共会被分为232/2^12 = 220块,则内存块号的范围应该是0-220-1,需要使用20个Bit存储,也就是至少需要3个字节(24B)进行存储。

(2)页号的字节

由于页表项是连续存储的,因此只要知道页号以及页表的起始地址就可以计算得到目的页号的块号,因此页表不需要存储页号,字节为0。

(3)综上,每一个页表项占3字节(在题中所给条件上)

(4)注意

image10
image10

并不存储物理地址

4.3.3 如何实现地址的转换

(1)虽然进程的各个页面是离散存放的,但是页面内部是连续存放的

image11
image11

(2)转换步骤:

image12
image12
4.3.4 如何确定一个逻辑地址对应的页号、页内偏移量

(1)例子:

image13
image13

我们知道,对于一个进程来说,各页面是离散存放的,但是在逻辑上各页面是连续存放的。页面内部不管是物理上还是逻辑上都是连续存放的。如图:

image14
image14

据此可以快速得到地址的转换逻辑:

image15
image15

(2)拓展

image16
image16

假设一个计算机是用32个二进制位表示逻辑地址,页面大小位4KB = 2^12B = 4096B

那么,进程数据的逻辑地址的后12位为页面偏移量,逻辑地址的前20位是页号,比如:

image17
image17

(3)我们知道,n号内存块的起始地址 = n*内存块大小。以我们刚才的例子为例:

image18
image18

则逻辑地址的后12位为业内偏移量,前20位为页号。由此我们可以得到结论:

image19
image19

4.4 总结

image20
image20

5 基本地址变换机构

5.1 概念

基本地址变换机构是一组用于实现逻辑地址到物理地址转换的硬件机构

5.2 变换步骤

5.2.1 页表寄存器(PTR)
image1
image1

5.3 变换步骤

假设页面的大小为2的整数次幂。当一个进程发生调度需要上处理机运行时,操作系统会将恢复进程的运行环境,将进程的PCB(存放页表的地址与页表的长度)放入页面寄存器中以方便操作系统进行管理,此外,程序计数器PC也会将进程下一条需要执行的指令的逻辑地址A放入,那么如何知道进程下一条指令的物理地址呢?

5.4 获取物理地址

(1)转换机构根据逻辑地址计算出页号P、页内偏移量W。假如页面大小为2的整数次幂,那么这个过程是很方便的

(2)假如一个进程的页表长度为M,意味着这个进程有M个页面,假如P>M,那么说明出错,操作系统会发生越界终端(内中断)

(3)确定M合法后,操作系统查询页表并找到页号对应的页表项,确定页面存放的内存块号。

(4)使用内存块号和页内偏移量计算得到物理地址(直接拼接),此时就可以访问内存单元了。

变换步骤如图:

image2
image2
5.4.1 几个基本概念

页表项长度、页表长度、页面大小。

image3
image3
5.4.2 转换例题
image4
image4
5.4.3 注意
image5
image5

三、对页表项大小的进一步探讨

image6
image6

所以,尽管3个字节已经可以表示所有的内存块,但是为了计算方便,经常会将页表项扩充为四个字节

image7
image7

5.5 总结

image8
image8

6 具有快表的地址变换机构

6.1 总览

image1
image1

6.2 什么是快表

image2
image2

6.3 引入快表后,地址的变换过程

  1. 快表是一种硬件设备,它的内容在每次进程切换之后都会删除,它的访问速度虽然很快,但是由于成本的限制,快表的存储空间不会很大。
  2. 引入快表后,操作系统在得到逻辑地址后会分离得到页号,接着进入快表去寻找页号对应的内存块号,假如没找到就会进入慢表(也就是之前的页表)进行寻找,并将寻找结果复制一份存入快表有方便下次寻找。其他步骤与无快表的地址变换过程类似。
image3
image3
  1. 示意图如下所示:
image4
image4

6.4 与快表命中率有关的题目

image5
image5

6.5 局部性原理

我们以下面这段代码为例:

image6
image6
时间局部性
image7
image7

对于while(i<100)这一条指令,程序在不久的将来是会频繁访问的,对于i这个变量,程序在不久的将来也是会频繁访问。这就是时间局部性。

空间局部性
image8
image8

对于a数组,它在内存中是连续存放的,假如此时系统访问了a10,那么a10周围的数据就很有可能会被频繁访问。这是空间局部性。

  1. 正是因为局部性原理,引入快表之后系统的速度就会快很多
image9
image9

6.6 知识总结

image10
image10

7 两级页表

7.1 知识总览

image1
image1

7.2 单极页表存在的问题

7.2.1 假设
image2
image2

页面大小为4KB,即212的字节,因此需要12个二进制位来存储,该计算机就支持32位,因此有20个二进制位表示页号,即可以表示220个页面,每个页面在页表中都必须对应一个页表项,因此页表中的页表项最多可以有220个,所以一个页表需要的最大空间为220*4 = 222B,而为了存储页表必须需要(222)/(2^12) = 2^10个连续的页框(页表必须连续存放)。

image3
image3
7.2.2 结论
image4
image4

7.3 对第一个问题的解决

7.3.1 思路

为了解决单极页表存在的几个问题,可以考虑将页表也进行分页并离散存储(单击页表中是将进程的页面离散存储)。

7.3.2 原理

对于给定的计算机配置信息(按字节寻址,支持32位,页面大小为4kb,页表项长度为4b),一个进程最多有220个页面,而每个页框可以存储的页表项个数为4kb/4b=210 = 1024个页表项。由此,可以将页表的2^20拆分成1024组,每组有1024个页表项,用一个二级页表存储单级页表,

7.3.3 逻辑结构的改变

32位二进制位中,前10位用来表示二级页表,后10位用来表示每个二级页表包含的单极页表,最后12位表示页面偏移量。

7.3.4 如何进行寻址

简单来说就是逐个寻找,先找一级地址,再在一级地址内找二级地址,最后根据页面偏移量找到对应的物理地址

image5
image5

7.4 对第二个问题的解决

image6
image6

当需要的页面不在内存中时会发生缺页中断(这是一个内中断),接着将目标页面从外存调入内存。

7.5 其他需要注意的细节

  1. 各级页表的大小不可以超过一个页面。如果分为两级页表后,各级页表还是超过一个页面,则应该采用更多的顶级页表。 TIPS:如果一个页表分为了好几页,那么不同页中可能页号有重叠,可能会照成无法区分顶级页表的后果。

例子:

image7
image7

业内偏移量位数实质上就是需要用几位二进制位来表示页面大小。这里4kb = 2^12,因此需要12位。每个页面包含的页表项个数位4kb/4b = 2^10个,因此一个页面最多可以包含10个二进制位。

由于页内偏移量为12位,因此页号位数为28位,而每级页表最多表示10位,因此此题需要分三级页表,分别占:8、10、10。逻辑结构如图:

image8
image8
  1. 假如没有快表结构,那么N级页表访问一个逻辑地址需要经历N+1次访存,其中访问各级网页需要培训

最后得到了逻辑地址对应的物理地址后还需1次访存。

7.6 总结

image9
image9

8 基本分段存储管理方法

8.1 总览

image1
image1

8.2 分段的基本概念

8.2.1 定义
image2
image2

类比于程序,其中的main函数是一段,而定义在main函数之外的其他函数也是一段。

8.2.2 特点

(1)当采用分段存储时,各段可以离散的存储,但是一个特定的段占据连续的内存空间。

(2)由于是按照逻辑功能划分模块,用户的编程更加方便,程序的可读性更加高。

(3)在编译程序时,系统会将段名转换为段号。

8.2.3 实例
image3
image3
8.2.4 逻辑地址结构
image4
image4

实例:对于编译后的机器汇编语言:

image5
image5

8.3 段表的基本概念

8.3.1 示意图
image6
image6

段表的作用类似于页表,记录各段的物理存储位置

8.3.2 段表的特点

(1)与页表类似,由于段在逻辑上在连续存储的,所以段号实际上是不需要被保存的。

只需记录段长以及各段的长度(基址)

image7
image7

(2)段表项的长度是固定的。如果段的逻辑结构中段内地址为16位,系统使用16个二进

制位就可以表示最大段长;而系统的物理地址肯定也对应一个最大字节长度(假设为4GB,

对应32位);段号无须存储。因此可以让每个段表项占16+32=48位,即6个字节。

image8
image8

8.4 地址的变换过程

  1. 进程在发生切换时,其PCB会被放入段表寄存器。系统在得到逻辑地址后,将其分解为段号S、段内地址W。
  2. 首先检查段号是否合法(段号是否越界)。假如S是否>=段表长度M(从段表寄存器中读取),那么段号越界,系统发生越界中断。注意此处因为段表长度至少为1,而段号从0开始,所以当S=M时也相当于越界。
  3. 将段号在段表中进行匹配,并得到段长C,此时如果W>=C,那么段长越界,发生越界中断。注意当采用页表时此处无须比较,因为页表的各页表项的长度是固定的,但是段表的段长是不固定的。假如没有越界,那么就取出基址,将基址与段内地址相加得到最后的物理地址。
  4. 示意图如下所示:
image9
image9

8.5 分段、分页管理的区别

8.5.1 存储逻辑的区别
image10
image10
8.5.2 分段的优点

分段比分页更容易实现信息的共享和保护

(1)信息的共享

假设计算机采用分段管理,且有这样一段代码空间

image11
image11

其中1号段是A、B号进程都想访问的,那么只需让各进程的段表项指向同一个段即可实现共享

而假如计算机采用分页管理,那么上述的代码空间应变为:

image12
image12

页面不是按照逻辑模块划分的,此时就很难实现信息的共享

(2)信息的保护

与信息共享类似,假如进程A不允许某个进程访问某个空间,只需将这段置标记为不可访问即可。而分页管理就很难实现

8.5.3 访问一个逻辑单元的访存次数
image13
image13

8.6 总结

image14
image14
image15
image15

9 段页式管理方法

9.1 总览

image1
image1

9.2 分段、分页的优缺点

image2
image2
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

9.3 段页式管理的基本概念

image4
image4

比如说:

image5
image5

9.4 段页式管理的逻辑地址结构

9.4.1 结构划分
image6
image6
9.4.2 解释
image7
image7
9.4.3 注意
image8
image8

9.5 段页式管理中的段表和页表

9.5.1 段表

基本结构:

image9
image9

由于各段被分为几页是不确定的,因此需要记录页表的长度,同时为了确定物理地址,还需要存放页表的起始地址(页表存放块号)。每一个段需要对应一个页表。

从图中可以看出,每个段表项的长度是相同的(只需记录页表长度即起始块号),因此段号是可以隐藏的。

9.5.2 页表

基本结构

image10
image10

页面的大小都是相同的,因此页号是隐藏的。只需记录各页号对应的内存块号即可。

image11
image11
9.5.3 总结

一个进程会被划分为多个段,所有的段构成一段表。而每一个段会被划分为多个页面,因此一个段对应一个页表。

总结:一个进程对应一个段表,但对应多个页表。

9.5.4 示意图
image12
image12

9.6 地址转换过程

首先,进程被调度时,其PCB中的段表起始地址F与段表长度M都会被复制放入操作系统的段表寄存器中;

接着读出逻辑地址中的段号S,并与段表长度进行比较,假如S>=M,(这里的=与前面的段式管理类似)说明越界,产生越界中断。

段号合法后,操作系统根据段表起始地址F查询到该进程对应的段表,根据段号查询到对应的段表项,

操作系统从逻辑地址读出页号P,并于段表项中的页表长度L进行对比,假如P>L,说明页号越界,产生越界中断。

页号合法后,操作系统从段表项中读出页表起始地址,根据页号查询页表得到内存块号,并结合逻辑地址中的业内偏移量得到最终的物理地址并访问。

具体过程示意图如下:

image13
image13

访存过程中,操作系统共需要访问三次内存。第一次是查询段表,第二次是查询页表,第三次是访问目标地址。我们也可以引入快表,以段号和页号作为关键字。

9.7 总结

image14
image14

10 总结

操作系统,如默默守护的守夜者,无声地管理硬件与软件的交流,为计算机创造和谐秩序。

它是无形的引导者,让复杂的任务变得井然有序,为用户提供无忧体验。

操作系统的巧妙设计,让计算机变得更加智能高效,让人与科技之间的交流更加顺畅。

在每一次启动中,它如信任的伙伴,带领我们进入数字世界的奇妙旅程。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.1 总览
  • 1.2 内存管理应有的功能
    • 1.2.1 内存空间的分配和回收
    • 1.2.2 从逻辑上扩充内存
    • 1.2.3 地址转换
    • 1.2.4 内存保护
  • 1.3 知识总结
  • 2 覆盖与交换
    • 2.1 总览
    • 2.2 覆盖技术
      • 2.2.1 覆盖技术的基本思想
      • 2.2.2 例子
      • 2.2.3 缺点
    • 2.3 交换技术
      • 2.3.1 基本思想
      • 2.3.2 待解决的问题
    • 2.4 总结
  • 3 连续内存分配
    • 3.1 总览
    • 3.2 单一连续分配
      • 3.2.1 思想
      • 3.2.2 优点
      • 3.2.3 缺点
    • 3.3 固定分区分配
      • 3.3.1 基本思想
      • 3.3.2 分类
      • 3.3.3 特点
      • 3.3.4 如何管理固定分区
      • 3.3.5 优缺点
    • 3.4 动态分区分配
      • 3.4.1 基本思想
      • 3.4.2 记录内存使用情况的数据结构
      • 3.4.3 空闲分区的分配
      • 3.4.4 分区的分配和回收
  • 4 基本分页存储管理的基本概念
    • 4.1 总览
    • 4.2 什么是分页存储
      • 4.2.1 将物理空间分页
      • 4.2.2 将逻辑空间分页
      • 4.2.3 空间的分配
      • 4.2.4 区分概念
    • 4.3 页表
      • 4.3.1 概述
      • 4.3.2 页表项的大小
      • 4.3.3 如何实现地址的转换
      • 4.3.4 如何确定一个逻辑地址对应的页号、页内偏移量
    • 4.4 总结
  • 5 基本地址变换机构
    • 5.1 概念
    • 5.2 变换步骤
      • 5.2.1 页表寄存器(PTR)
    • 5.3 变换步骤
    • 5.4 获取物理地址
      • 5.4.1 几个基本概念
      • 5.4.2 转换例题
      • 5.4.3 注意
    • 5.5 总结
  • 6 具有快表的地址变换机构
    • 6.1 总览
    • 6.2 什么是快表
    • 6.3 引入快表后,地址的变换过程
    • 6.4 与快表命中率有关的题目
    • 6.5 局部性原理
      • 时间局部性
      • 空间局部性
    • 6.6 知识总结
  • 7 两级页表
    • 7.1 知识总览
    • 7.2 单极页表存在的问题
      • 7.2.1 假设
      • 7.2.2 结论
    • 7.3 对第一个问题的解决
      • 7.3.1 思路
      • 7.3.2 原理
      • 7.3.3 逻辑结构的改变
      • 7.3.4 如何进行寻址
    • 7.4 对第二个问题的解决
    • 7.5 其他需要注意的细节
    • 7.6 总结
  • 8 基本分段存储管理方法
    • 8.1 总览
    • 8.2 分段的基本概念
      • 8.2.1 定义
      • 8.2.2 特点
      • 8.2.3 实例
      • 8.2.4 逻辑地址结构
    • 8.3 段表的基本概念
      • 8.3.1 示意图
      • 8.3.2 段表的特点
    • 8.4 地址的变换过程
    • 8.5 分段、分页管理的区别
      • 8.5.1 存储逻辑的区别
      • 8.5.2 分段的优点
      • 8.5.3 访问一个逻辑单元的访存次数
    • 8.6 总结
  • 9 段页式管理方法
    • 9.1 总览
    • 9.2 分段、分页的优缺点
    • 9.3 段页式管理的基本概念
    • 9.4 段页式管理的逻辑地址结构
      • 9.4.1 结构划分
      • 9.4.2 解释
      • 9.4.3 注意
    • 9.5 段页式管理中的段表和页表
      • 9.5.1 段表
      • 9.5.2 页表
      • 9.5.3 总结
      • 9.5.4 示意图
    • 9.6 地址转换过程
    • 9.7 总结
  • 10 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档