万字长文!非常详细!操作系统【内存管理】

本文涉及的产品
公网NAT网关,每月750个小时 15CU
简介: 万字长文!非常详细!操作系统【内存管理】



1 内存管理基础概念

1.1 总览

1.2 内存管理应有的功能

1.2.1 内存空间的分配和回收

示意图:

1.2.2 从逻辑上扩充内存

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

1.2.3 地址转换

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

三种装入方式为:

1.2.4 内存保护

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

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

以下图的进程1为例子

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

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

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

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

1.3 知识总结

2 覆盖与交换

2.1 总览

2.2 覆盖技术

2.2.1 覆盖技术的基本思想

2.2.2 例子

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

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

2.2.3 缺点

2.3 交换技术

2.3.1 基本思想

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

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

2.3.2 待解决的问题

对于问题1:

磁盘空间的示意图:

对于问题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 记录内存使用情况的数据结构

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

(1)空闲分区表

例子:

(2)空闲分区链

例子:

3.4.3 空闲分区的分配

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

3.4.4 分区的分配和回收

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

(1)分配操作

假设起始表内容如下:

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

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

(2)回收操作

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

直接修改表项内容

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

增加一个表项内容

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

合并表项内容

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

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

4.1 总览

4.2 什么是分页存储

4.2.1 将物理空间分页

4.2.2 将逻辑空间分页

方便管理员进行管理

4.2.3 空间的分配

4.2.4 区分概念

4.3 页表

4.3.1 概述

(1) 必要性

(2) 示意图

(3) 注意

4.3.2 页表项的大小

(1)块号的字节

假设:

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

(2)页号的字节

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

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

(4)注意

并不存储物理地址

4.3.3 如何实现地址的转换

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

(2)转换步骤:

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

(1)例子:

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

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

(2)拓展

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

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

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

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

4.4 总结

5 基本地址变换机构

5.1 概念

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

5.2 变换步骤

5.2.1 页表寄存器(PTR)

5.3 变换步骤

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

5.4 获取物理地址

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

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

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

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

变换步骤如图:

5.4.1 几个基本概念

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

5.4.2 转换例题

5.4.3 注意

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

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

5.5 总结

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

6.1 总览

6.2 什么是快表

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

1. 快表是一种硬件设备,它的内容在每次进程切换之后都会删除,它的访问速度虽然很快,但是由于成本的限制,快表的存储空间不会很大。

2. 引入快表后,操作系统在得到逻辑地址后会分离得到页号,接着进入快表去寻找页号对应的内存块号,假如没找到就会进入慢表(也就是之前的页表)进行寻找,并将寻找结果复制一份存入快表有方便下次寻找。其他步骤与无快表的地址变换过程类似。

3. 示意图如下所示:

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

6.5 局部性原理

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

时间局部性

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

空间局部性

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

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

6.6 知识总结

7 两级页表

7.1 知识总览

7.2 单极页表存在的问题

7.2.1 假设

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

7.2.2 结论

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 如何进行寻址

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

7.4 对第二个问题的解决

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

7.5 其他需要注意的细节

1. 各级页表的大小不可以超过一个页面。如果分为两级页表后,各级页表还是超过一个页面,则应该采用更多的顶级页表。

TIPS:如果一个页表分为了好几页,那么不同页中可能页号有重叠,可能会照成无法区分顶级页表的后果。

例子:

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

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

2. 假如没有快表结构,那么N级页表访问一个逻辑地址需要经历N+1次访存,其中,依次访问各级页需要N次,最后得到了逻辑地址对应的物理地址后还需1次访存。

7.6 总结

8 基本分段存储管理方法

8.1 总览

8.2 分段的基本概念

8.2.1 定义

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

8.2.2 特点

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

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

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

8.2.3 实例

8.2.4 逻辑地址结构

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

8.3 段表的基本概念

8.3.1 示意图

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

8.3.2 段表的特点

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

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

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

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

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

8.4 地址的变换过程

1. 进程在发生切换时,其PCB会被放入段表寄存器。系统在得到逻辑地址后,将其分解为段号S、段内地址W。

2. 首先检查段号是否合法(段号是否越界)。假如S是否>=段表长度M(从段表寄存器中读取),那么段号越界,系统发生越界中断。注意此处因为段表长度至少为1,而段号从0开始,所以当S=M时也相当于越界。

3. 将段号在段表中进行匹配,并得到段长C,此时如果W>=C,那么段长越界,发生越界中断。注意当采用页表时此处无须比较,因为页表的各页表项的长度是固定的,但是段表的段长是不固定的。假如没有越界,那么就取出基址,将基址与段内地址相加得到最后的物理地址。

4. 示意图如下所示:

8.5 分段、分页管理的区别

8.5.1 存储逻辑的区别

8.5.2 分段的优点

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

(1)信息的共享

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

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

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

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

(2)信息的保护

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

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 地址转换过程

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

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

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

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

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

具体过程示意图如下:

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

9.7 总结

10 总结

配套PDF资料下载:提取码·:ikun

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

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

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

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

渴望挑战操作系统的学习路径和掌握进阶技术?不妨点击下方链接,一同探讨更多操作系统的奇迹吧。我们推出了引领趋势的💻OS专栏:《OS从基础到进阶》 ,旨在深度探索OS的实际应用和创新。🌐🔍

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
相关文章
|
2月前
|
存储 Linux 调度
深入理解操作系统:从进程管理到内存分配
【8月更文挑战第44天】本文将带你深入操作系统的核心,探索其背后的原理和机制。我们将从进程管理开始,理解如何创建、调度和管理进程。然后,我们将探讨内存分配,了解操作系统如何管理计算机的内存资源。最后,我们将通过一些代码示例,展示这些概念是如何在实际操作系统中实现的。无论你是初学者还是有经验的开发者,这篇文章都将为你提供新的视角和深入的理解。
|
3月前
|
安全 索引
操作系统中的内存管理策略
【8月更文挑战第23天】
84 1
|
1月前
|
分布式计算 算法 大数据
探索操作系统的核心:调度与内存管理机制
【10月更文挑战第11天】 本文深入探讨了操作系统中两大核心功能——调度与内存管理机制。通过分析调度算法、进程状态转换及内存分配策略等关键方面,揭示了它们如何共同维护系统性能和稳定性。旨在为读者提供对操作系统内部运作的深刻理解,同时引起对优化策略的思考。
59 5
|
1月前
|
算法
深入理解操作系统:内存管理机制的探索之旅
【10月更文挑战第2天】在数字世界的浩瀚海洋中,操作系统犹如一艘精密的航船,承载着软件与硬件的和谐共舞。本文将揭开内存管理的神秘面纱,从基础概念到高级策略,引领读者领略操作系统内存分配的智慧。通过深入浅出的解释和生动的比喻,我们一同遨游在内存的江河之中,感受操作系统如何巧妙地协调资源,确保数据的有序流动。让我们跟随内存的脚步,探索那些隐藏在每次点击、每次命令背后的奥秘。
|
1月前
|
监控 开发者
深入理解操作系统:内存管理的艺术
【10月更文挑战第2天】在数字世界的幕后,操作系统扮演着至关重要的角色。本文将深入探索操作系统的心脏——内存管理,揭示它是如何协调和管理计算机的宝贵资源。通过浅显易懂的语言和生活化的比喻,我们将一起走进内存管理的奥秘世界,了解它的原理、机制以及为何对整个系统的性能和稳定性有着不可替代的影响。无论你是技术新手还是资深开发者,这篇文章都将为你打开新的视角,让你对日常使用的设备有更深层次的认识和尊重。
|
1月前
|
缓存 算法 调度
深入浅出操作系统:从进程管理到内存优化
本文旨在为读者提供一次深入浅出的操作系统之旅。我们将从进程管理的基本概念出发,逐步深入到内存管理的复杂世界,最终探索如何通过实践技巧来优化系统性能。文章将结合理论与实践,通过代码示例,帮助读者更好地理解操作系统的核心机制及其在日常技术工作中的重要性。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开一扇通往操作系统深层次理解的大门。
|
1月前
|
存储 算法 C语言
MacOS环境-手写操作系统-17-内存管理算法实现
MacOS环境-手写操作系统-17-内存管理算法实现
36 0
|
1月前
|
Java C语言 iOS开发
MacOS环境-手写操作系统-16-内存管理 解析内存状态
MacOS环境-手写操作系统-16-内存管理 解析内存状态
35 0
|
1月前
|
存储 算法 C语言
MacOS环境-手写操作系统-15-内核管理 检测可用内存
MacOS环境-手写操作系统-15-内核管理 检测可用内存
35 0
|
2月前
|
Python
python对电脑的操作,获取几核,获取操作系统,获取内存
python对电脑的操作,获取几核,获取操作系统,获取内存