文章目录

  • 1. 内存的基础知识
    • 1.1 什么是内存,有何作用
    • 1.2 进程运行的基本原理
      • 1.2.1 指令的工作原理
      • 1.2.2 逻辑地址 VS 物理地址
    • 1.3 如何实现地址转换(逻辑 -> 物理)
      • 1.3.1 绝对装入
      • 1.3.2 可重定位装入(静态重定位)
      • 1.3.3 动态运行时装入(动态重定位)
    • 1.4 从写程序到程序运行的过程
    • 1.5 链接的三种方式
      • 1.5.1 静态链接
      • 1.5.2 装入时动态链接
      • 1.5.3 运行时动态链接
    • 1.6 总结
  • 2. 内存管理的概念
    • 2.1 内存空间的分配与回收
      • 2.1.1 连续分配管理方式
        • Ⅰ 单一连续分配
        • Ⅱ 固定分区分配
        • Ⅲ 动态分区分配
        • Ⅳ 总结
      • 2.1.2 动态分区分配算法
        • Ⅰ 首次适应算法
        • Ⅱ 最佳适应算法
        • Ⅲ 最坏适应算法
        • Ⅳ 邻近适应算法
        • Ⅴ 总结
    • 2.2 内存空间的扩充
      • 2.2.1 覆盖技术
      • 2.2.2 交换技术
      • 2.2.3 总结
    • 2.3 地址转换
      • 2.3.1 连续分配的地址转换
      • 2.3.2 总结
    • 2.4 存储保护
      • 2.4.1 方式
      • 2.4.2 总结

1. 内存的基础知识

在这里插入图片描述

1.1 什么是内存,有何作用

内存可存放数据。程序执行前需要先放到内存中才能被CPU处理——内存也是为了缓和CPU与磁盘之间的速度矛盾

在这里插入图片描述

补充知识:

在这里插入图片描述

1.2 进程运行的基本原理

1.2.1 指令的工作原理

指令的工作基于“地址”。每个地址对应一个数据的存储单元。

在这里插入图片描述
可见,我们写的代码要翻译成CPU能识别的指令。这些指令会告诉CPU应该去内存的哪个地址读/写数据,这个数据应该做什么样的处理。在此例中,我们默认让这个进程的相关内容从地址0开始连续存放,指令中的地址参数直接给出了变量x的实际存放地址(物理地址)

1.2.2 逻辑地址 VS 物理地址

  • C语言程序经过编译、链接处理后,生成装入模块,即可执行文件(*.exe)
  • 程序经过编译、链接后生成了装入模块,其中装入模块生成的指令中指明的是逻辑地址(相对地址)
  • 物理地址(绝对地址) 是实际内存硬件中的地址。将装入模块装入至内存中,此时会发生地址转换,将逻辑地址转换为物理地址

在这里插入图片描述

1.3 如何实现地址转换(逻辑 -> 物理)

三种装入方式:

    1. 绝对装入
    1. 可重定位装入(静态重定位)
    1. 动态运行时装入(动态重定位)

1.3.1 绝对装入

绝对装入:在编译时,如果知道程序将放到内存中的哪个位置,编译程序将产生绝对地址的目标代码。装入程序按照装入模块中的地址,将程序和数据装入内存。

在这里插入图片描述
绝对装入只适用于单道程序环境。程序中使用的绝对地址,可在编译或汇编时给出,也可由程序员直接赋予。通常是在编译或汇编时再转换为绝对地址。

1.3.2 可重定位装入(静态重定位)

静态重定位:又称可重定位装入。编译、链接后的装入模块的地址都是从0开始,指令中使用的地址、数据存放的地址都是相对于起始地址而言的逻辑地址。可根据内存当前情况,将装入模块装入到内存的适当位置。装入时对地址进行“重定位”,将逻辑地址变换为物理地址(地址变换是在装入时一次完成的)。

在这里插入图片描述
静态重定位的特点是在一个作业装入内存时,必须分配其要求的全部内存空间,如果没有足够的内存,就不能装入该作业。作业一旦进入内存后,在运行期间就不能再移动,也不能再申请内存空间。

1.3.3 动态运行时装入(动态重定位)

动态重定位:又称动态运行时装入。编译、链接后的装入模块的地址都是从0开始的。装入程序把装入模块装入内存后,并不会立即把逻辑地址转换为物理地址,而是把地址转换推迟到程序真正要执行时才进行。因此装入内存后所有的地址依然是逻辑地址。这种方式需要一个重定位寄存器的支持。

在这里插入图片描述
采用动态重定位时允许程序在内存中发生移动。并且可将程序分配到不连续的存储区中;在程序运行前只需装入它的部分代码即可投入运行,然后在程序运行期间,根据需要动态申请分配内存;便于程序段的共享,可以向用户提供一个比存储空间大得多的地址空间。

1.4 从写程序到程序运行的过程

在这里插入图片描述

1.5 链接的三种方式

1.5.1 静态链接

静态链接:在程序运行之前,先将各目标模块及它们所需的库函数连接成一个完整的可执行文件(装入模块),之后不再拆开。

在这里插入图片描述

1.5.2 装入时动态链接

装入时动态链接:将各目标模块装入内存时,边装入边链接的链接方式。

在这里插入图片描述

1.5.3 运行时动态链接

运行时动态链接:在程序执行中需要该目标模块时,才对它进行链接。其优点是便于修改和更新,便于实现对目标模块的共享。

在这里插入图片描述

1.6 总结

在这里插入图片描述

2. 内存管理的概念

在这里插入图片描述
操作系统作为系统资源的管理者,当然也需要对内存进行管理,要管些什么呢?

    1. 负责内存空间的分配与回收
    1. 需要提供某种技术从逻辑上对内存空间进行扩充
    1. 需要提供地址转换功能,负责程序的逻辑地址与物理地址的转换
    1. 需要提供内存保护功能。保证各进程在各自存储空间内运行,互不干扰

2.1 内存空间的分配与回收

在这里插入图片描述

  • 内部碎片:分配给某进程的内存区域中,有些部分没有用上
  • 外部碎片:是指内存中的某些空闲分区由于太小而用不上或难以利用

2.1.1 连续分配管理方式

连续分配:指为用户进程分配的必须是一个连续的内存空间

Ⅰ 单一连续分配
  • 在单一连续分配方式中,内存被分为系统区用户区。系统区通常位于内存的低地址部分,用于存放操作系统的相关数据;用户区用于存放用户进程相关数据
  • 内存中只能有一道用户程序,用户程序独占整个用户区空间

优缺点:

  • 优点:实现简单;无外部碎片;可以采用覆盖技术扩充内存;不一定需要采用内存保护
  • 缺点:只能用于单用户、单任务的操作系统中;有内部碎片;存储器利用率极低

在这里插入图片描述

Ⅱ 固定分区分配

为了能在内存中装入多道程序,且这些程序之间又不会相互干扰,于是将整个用户空间划分为若干个固定大小的分区,在每个分区中只装入一道作业这样就形成了最早的、最简单的一种可运行多道程序的内存管理方式。

在这里插入图片描述

  • 分区大小相等:缺乏灵活性,但是很适用于用一台计算机控制多个相同对象的场合
  • 分区大小不等:增加了灵活性,可以满足不同大小的进程需求。根据常在系统中运行的作业大小情况进行划分

在这里插入图片描述

操作系统需要建立一个数据结构——分区说明表,来实现各个分区的分配与回收。每个表项对应一个分区,通常按分区大小排列。每个表项包括对应分区的大小、起始地址、状态(是否已分配)

在这里插入图片描述

当某用户程序要装入内存时,由操作系统内核程序根据用户程序大小检索该表,并结合一定算法从中找到一个能满足大小的、未分配的合适分区,将之分配给该程序,然后修改状态为“已分配”。

优缺点:

  • 优点:实现简单,无外部碎片
  • 缺点:a. 当用户程序太大时,可能所有的分区都不能满足需求,此时不得不采用覆盖技术来解决,但这又会降低性能;b. 会产生内部碎片,内存利用率低
Ⅲ 动态分区分配

动态分区分配又称为可变分区分配。这种分配方式不会预先划分内存分区,而是在进程装入内存时,根据进程的大小动态地建立分区,并使分区地大小正好适合进程地需要。因此用户分区地大小和数目是可变的。

在这里插入图片描述

    1. 系统要用什么样的数据结构记录内存的使用情况?
      在这里插入图片描述

在这里插入图片描述

    1. 当很多个空闲分区都能满足需求时,应该选择哪个分区进行分配?

在这里插入图片描述

在下一小节将介绍动态分区分配算法

    1. 如何进行分区的回收操作?假设系统采用的数据结构是“空闲分区表”如何分配?

情况一:回收区的后面有一个相邻的空闲分区(回收进程4(4MB))

在这里插入图片描述

情况二:回收区的前面有一个相邻的空闲分区(回收进程3(18MB))

在这里插入图片描述
情况三:回收区的前、后各有一个相邻的空闲分区(回收进程4(4MB))
在这里插入图片描述
情况四:回收区的前、后都没有相邻的空闲分区(回收进程2(14MB))
优缺点:

  • 动态分区分配没有内部碎片,但是有外部碎片
  • 如果内存中空闲空间的总和本来可以满足某进程的要求,但由于进程需要的是一整块连续的内存空间,导致这些“碎片”不能满足进程的需求。所以可以通过紧凑(拼凑,Compaction)技术来解决外部碎片。
  • 动态分区分配应使用动态运行时装入方式。采用“紧凑”技术之后,需更新重定位寄存器的值并且同时更新空闲分区表或空闲分区链,使其对应上“紧凑”之后空间块的情况
Ⅳ 总结

在这里插入图片描述

2.1.2 动态分区分配算法

动态分区分配算法:在动态分区分配方式中,当很多个空闲分区都能满足需求时,应选择哪个分区进行分配?

在这里插入图片描述

Ⅰ 首次适应算法
  • 算法思想:每次都从低地址开始查找,找到第一个能满足大小的空闲分区。
  • 如何实现:空闲分区以地址递增的次序排序。每次分配内存时顺序查找空闲分区链(或空闲分区表),找到大小能满足要求的第一个空闲分区

如下图所示,依次为进程5和进程6分配空闲分区:

在这里插入图片描述

Ⅱ 最佳适应算法
  • 算法思想:由于动态分区分配是一种连续分配方式,为各进程分配的空间必须是连续的一整片区域。因此为了保证当“大进程”到来时能有连续的大片空间,可以尽可能多地留下大片的空闲区。即优先使用满足分配的更小的空闲区
  • 如何实现:空闲分区按容量递增次序链接。每次分配内存时顺序查找空闲分区链(或空闲分区表),找到大小能满足要求的第一个空闲分区。

如下图所示,依次为进程5和进程6分配空闲分区:

在这里插入图片描述

缺点:每次都选最小的分区进行分配,会留下越来越多的、很小的、难以利用的内存块。因此这种方式会产生很多的外部碎片。且要维护空闲分区按容量递增次序链接必然会使用排序,这也是性能的一种消耗。

Ⅲ 最坏适应算法
  • 又称最大适用算法
  • 算法思想:为了解决最佳适应算法的问题——即留下太多难以利用的小碎片,可以在每次分配时优先使用最大的连续空闲区,这样分配后剩余的空闲区就不会太小,更方便使用
  • 如何实现:空闲分区按容量递减次序链接。每次分配内存时顺序查找空闲分区链(或空闲分区表),找到大小能满足要求的第一个空闲分区

如下图所示,依次为进程5和进程6分配空闲分区:
在这里插入图片描述
缺点:每次都选最大的分区进行分配,虽然可以让分配后留下的
空闲区更大,更可用,但是这种方式会导致较大的连续空闲区被
迅速用完。如果之后有“大进程”到达,就没有内存分区可用了。

Ⅳ 邻近适应算法
  • 算法思想:首次适应算法每次都从链头开始查找的。这可能会导致低地址部分出现很多小的空闲分区,而每次分配查找时,都要经过这些分区,因此也增加了查找的开销。如果每次都从上次查找结束的位置开始检索,就能解决上述问题。
  • 如何实现:空闲分区以地址递增的顺序排列(可排成一个循环链表)。每次分配内存时从上次查找结束的位置开始查找空闲分区链(或空闲分区表),找到大小能满足要求的第一个空闲分区。

在这里插入图片描述
分析:

  • 首次适应算法每次都要从头查找,每次都需要检索低地址的小分区。但是这种规则也决定了当低地址部分有更小的分区可以满足需求时,会更有可能用到低地址部分的小分区,也会更有可能把高地址部分的大分区保留下来(首次适应算法隐含了最佳适应算法的优点)
  • 邻近适应算法的规则可能会导致无论低地址、高地址部分的空闲分区都有相同的概率被使用,也就导致了高地址部分的大分区更可能被使用,划分为小分区,最后导致无大分区可用(邻近适应算法隐含了最大适应算法的缺点)
  • 综合来看,四种算法中,首次适应算法的效果反而更好
Ⅴ 总结

在这里插入图片描述

2.2 内存空间的扩充

在这里插入图片描述

2.2.1 覆盖技术

早期的计算机内存很小,比如IBM推出的第一台PC机最大只支持1MB大小的内存。因此经常会出现内存大小不够的情况。后来人们引入了覆盖技术,用来解决“程序大小超过物理内存总和”的问题

覆盖技术的思想:

  • 程序分为多个段(多个模块)。常用的段常驻内存,不常用的段在需要时调入内存
  • 内存中分为一个“固定区”和若干个“覆盖区”
  • 需要常驻内存的段放在“固定区”中,调入后就不再调出(除非运行结束)
  • 不常用的段放在“覆盖区”,需要用到时调入内存,用不到时调出内存
  • 必须由程序员声明覆盖结构,操作系统完成自动覆盖。缺点:对用户不透明(可见),增加了用户编程负担。覆盖技术只用于早期的操作系统,现在已成为历史
    在这里插入图片描述

2.2.2 交换技术

  • 交换(对换)技术的设计思想:内存空间紧张时,系统将内存中的某些进程暂时换出外存,把外存中某些已具备运行条件的进程换入内存(进程在内存与磁盘间动态调度)

在这里插入图片描述

  • 中级调度(内存调度),就是要决定将哪个处于挂起状态的进程重新调入内存
  • 暂时换出外存等待的进程状态为挂起状态(挂起态)
  • 挂起态又可以进一步细分为就绪挂起、阻塞挂起两种状态

在这里插入图片描述

在这里插入图片描述

2.2.3 总结

在这里插入图片描述

2.3 地址转换

为了使编程更方便,程序员写程序时应该只需要关注指令、数据的逻辑地址。而逻辑地址到物理地址的转换(这个过程称为地址重定位)应该由操作系统负责,这样就保证了程序员写程序时不需要关注物理内存的实际情况。

2.3.1 连续分配的地址转换

连续分配对应了三种装入方式,三种装入方式的地址转换各不同,如下所示:

在这里插入图片描述

2.3.2 总结

在这里插入图片描述

2.4 存储保护

2.4.1 方式

内存保护可采取两种方式:

  • 方法一:在CPU中设置一对上、下限寄存器,存放进程得上、下限地址。进程得指令要访问某个地址时,CPU检查是否越界

在这里插入图片描述

  • 方法二:采用重定位寄存器(又称基址寄存器)和界地址寄存器(又称限长寄存器)进行越界检查。重定位寄存器中存放的是进程的起始物理地址。界地址寄存器中存放的是进程的最大逻辑地址

在这里插入图片描述

2.4.2 总结

在这里插入图片描述
本篇文章只介绍了内存管理中的连续分配管理方式,而非连续分配管理方式和内存虚拟化技术将在后续文章中介绍

参考:《王道计算机考研 操作系统》
bilibili: https://www.bilibili.com/video/av70156862

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/85601.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/85601.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/85601.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

医学图像处理期末复习

目录 考试范围第1章 绪论1.1 数字图像处理的概念1.2 数字图像处理的应用领域1、医学领域2、其他领域 1.3 数字图像处理基础1.4 数字图像基础运算 第2章 医学图像灰度变换与空间滤波2.1 医学图像灰度变换线性灰度变换非线性灰度变换 2.2 直方图均衡化√2.3 空间平滑滤波线性空间…

类图:软件世界的“建筑蓝图”

本文来自「大千AI助手」技术实战系列,专注用真话讲技术,拒绝过度包装。 类图(Class Diagram):软件世界的“建筑蓝图” 类图(Class Diagram)是统一建模语言(UML) 中最重要…

利用DevEco Studio对RK3588的HiHopesOS-4.1.110(OpenHarmony)进行Qt程序编写

文章目录 热身准备添加Qt库运行qml程序 热身 可以先看我这篇文章【DevEco Studio中使用Qt,编写HarmonyOS程序】 准备 板子的主要信息 目前由于系统版本(API 11)及其他原因,只能用4.1版本的DevEcoStudio来编写,更高…

设计模式精讲 Day 5:原型模式(Prototype Pattern)

【设计模式精讲 Day 5】原型模式(Prototype Pattern) 文章内容 在“设计模式精讲”系列的第5天,我们将深入讲解原型模式(Prototype Pattern)。作为创建型设计模式之一,原型模式通过复制已有对象来创建新对…

深度学习——第2章习题2-1分析为什么平方损失函数不适用于分类问题

深度学习——第2章习题2-1 《神经网络与深度学习》——邱锡鹏 2-1 分析为什么平方损失函数不适用于分类问题。 平方损失函数(Quadratic Loss Function)经常用在预测标签y为实数值的任务中,定义为 L ( y , f ( x ; θ ) ) 1 2 ( y − f (…

【Linux】运行脚本后打屏同时保存到本地

命令: sh run.sh 2>&1 | tee output.log sh run.sh 2>&1 | tee output_$(date "%Y%m%d%H%M").log作用:运行脚本,并同时将输出(包括标准输出和错误输出)显示到终端,并保存到文件中…

Spark 在小众日常场景中的实战应用:从小店数据到社区活动

Spark 在小众日常场景中的实战应用:从小店数据到社区活动​ 提起 Spark,大家往往会联想到大型互联网公司的数据处理、金融行业的复杂分析。但实际上,Spark 在许多小众、贴近生活的场景中也能大显身手。结合学习与实践,我探索了 S…

mysql 执行计划 explain命令 详解

explain id :select查询的序列号,包含一组数字,表示查询中执行select子句或操作表的顺序select_type:查询类型 或者是 其他操作类型table :正在访问哪个表partitions :匹配的分区type :访问的类…

让大模型“更懂人话”:对齐训练(RLHF DPO)全流程实战解析

网罗开发 (小红书、快手、视频号同名) 大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等…

GO 原子操作面试题及参考答案

Go 的 sync/atomic 包和 sync.Mutex 的根本区别是什么? Go 语言中的 sync/atomic 包和 sync.Mutex 都用于处理并发编程中的同步问题,但它们的实现机制、应用场景和性能特性存在根本差异。理解这些差异对于编写高效、安全的并发代码至关重要。 sync/atomi…

MATLAB 山脊图绘制全解析:从数据生成到可视化进阶

一、引言:当数据分布拥有「层次感」—— 山脊图的魅力​ 在数据可视化的世界里,我们常常需要同时展示多个分布的形态差异。传统的重叠密度图虽然能呈现整体趋势,但当分布数量较多时,曲线交叠会让画面变得杂乱。这时候&#xff0c…

跨境电商每周资讯—6.16-6.20

1. Instagram 在亚太地区逐渐超越 TikTok 在整个亚太地区,Instagram用户数量正逐渐超过TikTok。预计2025年日本Instagram用户数量将增至4440万,印度今年用户数量将增长10%,领跑亚太。与之形成对比的是,TikTok在一些国家增长速度放…

计算机网络 网络层:数据平面(一)

前一节学习了运输层依赖于网络层的主机到主机的通信服务,提供各种形式的进程到进程的通信。了解这种主机到主机通信服务的真实情况,是什么使得它工作起来的。 在本章和下一章,将学习网络层实际是怎样实现主机到主机的通信服务。与运输层和应用…

Suna本地部署详细教程

一、安装基础环境 # 1、创建环境 conda create -n suna python3.11.7# 2、激活虚拟环境 conda activate suna# 3、安装jupyter和ipykernel pip install jupyter ipykernel# 4、将虚拟环境添加到jupyter # python -m ipykernel install --user --namemyenv --display-name"…

LeetCode 每日一题打卡|若谷的刷题日记 3day--最长连续序列

1.最长连续序列 题目: 给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。 请你设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例 1: 输入:nums [1…

EfficientVLA:面向视觉-语言-动作模型无训练的加速与压缩

25年6月来自上海交大、哈工大、西安交大和电子科大(成都)的论文“EfficientVLA: Training-Free Acceleration and Compression for Vision-Language-Action Models”。 视觉-语言-动作 (VLA) 模型,特别是基于扩散的架构,展现出具…

wireshark抓包分析TCP数据包

1、直接从TCP的三次握手开始说起 三次握手就是客户与服务器建立连接的过程 客户向服务器发送SYN(SEQ=x)报文,然后就会进入SYN_SEND状态服务器收到SYN报文之后,回应一个SYN(SEQ=y)ACK(ACK=x+1)报文,然后就会进入SYN_RECV状态客户收到服务器的SYN报文,回应一个ACK(AC…

同等学力申硕-计算机统考-历年真题和备考经验

同等学力申请硕士学位考试是比较适合在职人员的提升学位方式,了解过的人应该都知道,现在社会的竞争压力越来越大,为了提高职业生存能力,提升学位在所难免。 一、已有计算机统考历年真题资料 报名过同等学力申硕计算机专业的朋友都…

OSI网络通信模型详解

OSI 模型就是把这整个过程拆解成了 7 个明确分工的步骤,每一层只负责自己那一摊事儿,这样整个系统才能顺畅运转,出了问题也容易找到“锅”在谁那。 核心比喻:寄快递 📦 想象你要把一份重要的礼物(你的数据…

C++ 检测文件大小和文件传输

检测文件的大小 你可以通过标准 C/C 的文件 API 很方便地获取文件的字节大小&#xff0c;以下是几种常用方法&#xff1a; ✅ 方法一&#xff1a;使用 stat() 函数&#xff08;推荐&#xff09; #include <sys/stat.h> #include <stdio.h>off_t get_file_size(co…