操作系统【三】内存管理基础+连续内存分配

内存的基础知识

内存分为按字节编址(8位)和字编制(不同计算机不一样,64位计算机就是64位,即8个字节)

相对地址=逻辑地址 绝对地址=物理地址

在这里插入图片描述

从逻辑地址到物理地址的转换由装入解决。

装入的三种方式

  1. 绝对装入:在编译时知道程序放在内存中的哪个位置,编译程序将产生绝对地址的目标代码。
    灵活性很低,只适用于单道程序环境,只有单道程序环境可以在程序运行之前就能确定程序将要放入哪个位置
  2. 静态重定位:又称为可重定位装入。装入模块全部使用逻辑地址,在装入的时候将逻辑地址全部转换为物理地址。
    特点是必须分配其要求的全部内存空间,如果没有足够的内存,就不能装入作业。作业一旦进入内存后,在运行期间就不能再移动,也不能再申请内存空间。
  3. 动态重定位:又称为动态运行时装入。装入模块使用相对地址。相对地址到物理地址的转变要等到实际运行的时候才能确定。因此装入内存后所有的地址仍然是逻辑地址。这种方式需要一个重定位寄存器的支持。
    重定位寄存器:存放装入模块存放的起始位置。当实际运行的时候实时地将逻辑地址转换为物理地址。
    采用动态重定位允许程序在内存中发生移动。可以将程序分配到不连续的存储区:在程序运行前只需要装入他的部分代码即可投入运算,然后在程序运行期间根据需要动态申请分配内存,便于程序段的共享,可以向用户提供一个比存储空间大得多的地址空间。

链接的三种方式

  1. 静态链接:在程序运行之前,先将各个目标模块以及他们所需要的库函数连接成一个完整的可执行文件(装入模块),之后不再拆开。
  2. 装入时动态链接:将各目标模块装入内存时,边装入边链接
  3. 运行时动态链接:在程序执行中需要该目标模块时才对他进行链接,优点是便于修改和更新,便于实现对目标模块的共享。

内存管理需要解决的问题

  1. 内存空间的分配与回收
  2. 操作系统需要提供某种技术从逻辑上对内存空间进行扩充
  3. 地址转换(三种装入方式:绝对装入、可重定位装入/静态重定位、动态运行时装入/动态重定位)
  4. 内存保护:保护各个进行运行互不干扰
    方法一:在CPU中设置一对上下限寄存器,存放进程的上下限地址。进程的指令要访问某个地址时,CPU检查是否越界。
    方法二:采用重定位寄存器(基址寄存器)和界地址寄存器(限长寄存器)进行越界检查。重定位寄存器中存放的是进程的起始物理地址,界地址寄存器中存放的是进程的最大逻辑地址。

内存空间的扩充

覆盖技术

用于解决“程序大小超过物理内存总和”的问题

覆盖技术的思想:将程序分为多个段(多个模块)。常用的段常驻内存,不常用的段在需要时调入内存。

内存中分为固定区 和 若干个覆盖区

需要常驻内存的段放入固定区中,调入后就不再调出(除非运行结束)。不常用的段就放在覆盖区中。按照自身逻辑结构,让那些不可能同时被访问的程序段共享同一个覆盖区。

在这里插入图片描述

程序员必须声明覆盖结构,操作系统完成自动覆盖。缺点:对用户不透明,增加了用户编程负担。(已经没人用了)

交换技术

也叫做对换技术:内存空间紧张时,系统将内存中某些进程暂时换到外存中,把外存中某些已经具备运行条件的进程换入内存(中级调度)

进程的PCB需要常驻内存

中级调度(内存调度):决定将哪个处于挂起状态的进程重新调入内存。
暂时换出外存等待的进程的状态为挂起状态。

挂起状态可以分为:就绪挂起、阻塞挂起两种状态。

在这里插入图片描述

  1. 应该在外存的什么位置保存被换出的进程?
    具有对换功能的操作系统中,通常把磁盘文件分为文件区对换区两部分。文件区主要用于存放文件,主要追求存储空间的利用率,因此对文件区空间的管理采用离散分配方式;对换区空间只占磁盘空间的一小部分,被换出的进程数据就存放在对换区。对于对换的速度直接影响到系统的整体速度,因此对换区空间的管理主要追求换入换出速度,因此通常对换区采用连续分配方式。总之,对换区的I/O速度比文件区的更快。

  2. 应该什么时候交换?
    交换通常在许多进程运行且内存吃紧时进行,而系统负荷降低就暂停。例如:在发现许多进程运行时经常发生缺页,就说明内存紧张,因此可以换出一些进程;如果缺页率明显下降,就可以暂停换出。

  3. 应该换出哪些进程?
    可优先换出阻塞进程;可换出优先级低的进程;为了防止优先级低的进程饥饿,有的系统还会考虑进程在内存的驻留时间。。。(PCB常驻内存

覆盖技术和交换技术的区别:

  • 覆盖是同一个程序或者进程中
  • 交换是在不同进程/作业中的

内存分配

连续分配管理

系统为用户进程分配必须是一个连续的内存空间。

单一连续分配

内存被分为系统区和用户区。内存中只能有一道用户程序,用户程序独占整个用户区空间。

优点:实现简单,没有外部碎片;可以采用覆盖技术扩充内存;不一定需要采取内存保护(eg:早期的MS-DOS)
缺点:只能用于单用户、单任务的操作系统;有内部碎片;存储器利用率极低

内部碎片:分配给进程的内存区域中,如果有些部分没有用上,就是内部碎片。

固定分区分配

将用户区划分为若干个固定大小的分区,在每个分区中之状如一道作业,这样就形成了最早的,最简单的一种可运行多道程序内存管理方式。

如果分区大小相等:缺乏灵活性,但是很适用用于同一台计算机控制多个相同对象。

如果分区大小不等:增加了灵活性,可以满足不同大小进程的需求。产生一些大的,产生一些小的。

分区说明表:来实现每个分区的分配与回收。每个表象对应一个分区,通常按分区大小分配。

在这里插入图片描述
优点:实现简单,无外部碎片

缺点:当用户程序太大时,可能所有分区都不能满足需求,用覆盖技术来解决可能降低性能;可能产生内部碎片,内存利用率低

动态分区分配

又称为可变分区分配。根据进程装入内存时的大小动态建立分区。因此系统分区的大小和数目时可以改变的。

  1. 操作使用什么样的数据结构记录内存
  • 空闲分区表:每个空闲分区对应一个表项
  • 空闲分区链:每个分区的起始部分和末尾部分分别设置前向指针和后向指针。起始部分处还可以记录分区大小等信息。
  1. 当很多空闲分区都能够满足需求时选择哪一个

使用动态分区分配算法

  1. 分区的分配和回收

动态分区没有内部碎片,但是有外部碎片。
内部碎片:分配给某进程的内部区域中如果有些部分没有用上
外部碎片:内存中的某些空闲分区由于太小而难以利用

为了解决外部碎片,我们可以采用紧凑技术,通过将不同进程的内存空间挪挪位将不连续的内存空间凑在一起。为了实现这种技术我们应该是用动态重定位的装入方式,每次紧凑之后都将进程的起始地址都放在基址寄存器(重定位寄存器)中。

动态分区分配算法

首次适应算法

每次从低地址开始查找,找到第一个能够满足大小的空闲分区
实现:空闲分区以地址递增的次序排列。每次分配内存时顺序查找空闲分区表(链),找到第一个满足的空闲分区。

最佳适应算法

尽可能留下大片的空闲区,优先使用更小的空闲区
实现:空闲分区按照容量递增的次序链接,每次分配内存时找到第一个满足的空闲分区。每次分配以后还需要对空闲分区排序使其按照容量大小递增。

缺点:每次采用最小的分区选择,会产生很多外部碎片

最坏适应算法

每次分配优先使用最大的连续空闲区,这样每次分配以后空闲区就不会太小。
实现:空闲分区按照容量递减链接。每次分配使用第一个空闲分区(如果第一个都不满足就GG了)然后对空闲分区进行排序

缺点:如果大进程到达就会导致没有空间使用

邻近适应算法

首次适应算法每次从开始查找导致开始部分出现很多外部碎片。为了解决这个问题,每次从上次查找结束的位置开始检索。
实现:空闲分区以地址递增的顺序排列成循环链表。每次内存分配从上次查找结束的位置开始查找。同首次适应算法一样每次分配以后不需要对链表重新排列。

首次适用算法虽然容易产生外部碎片,但是可能保留大分区。邻近适应算法虽然减少产生外部碎片,但是可能没有外部碎片。

在这里插入图片描述
综合来看首次适应算法还是比较优秀的。

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

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

相关文章

MSG_PEEK标志

https://blog.csdn.net/aspnet_lyc/article/details/28937229 MSG_PEEK标志可以用来读取套接字接收队列中可读的数据,一些情况会用到它,比如为了避免不阻塞而先检查套接字接收队列中可读的数据长度,再采取相应操作。当然,不阻塞也…

C++的单例模式与线程安全单例模式(懒汉/饿汉)

https://www.cnblogs.com/qiaoconglovelife/p/5851163.html1 教科书里的单例模式我们都很清楚一个简单的单例模式该怎样去实现:构造函数声明为private或protect防止被外部函数实例化,内部保存一个private static的类指针保存唯一的实例,实例的…

计算矩阵的逆和行列式的值(高斯消元+LU分解)

计算矩阵的逆 选主元的高斯消元法 朴素的高斯消元法是将矩阵A和单位矩阵放在一起,通过行操作(或者列操作)将A变为单位矩阵,这个时候单位矩阵就是矩阵A的逆矩阵。从上到下将A变为上三角矩阵的复杂度为O(n3n^3n3),再从下…

Linux网络编程——tcp并发服务器(epoll实现)

https://blog.csdn.net/lianghe_work/article/details/46551871通过epoll实现tcp并发回执服务器&#xff08;客户端给服务器发啥&#xff0c;服务器就给客户端回啥&#xff09; 代码如下&#xff1a;#include <string.h>#include <stdio.h>#include <stdlib.h&g…

证明AVL树的上界和下界

对于n个节点的AVL树&#xff0c;其高度最低的时候肯定为叶子节点只在最后一层和倒数第二层的时候。即对于2k−1<n≦2k1−12^k-1< n\leqq 2^{k1}-12k−1<n≦2k1−1的时候下界都为kkk。因此下界为h┌log2(n1)┐−1h\ulcorner log_2(n1)\urcorner-1h┌log2​(n1)┐−1 对…

浅谈dup和dup2的用法

https://blog.csdn.net/u012058778/article/details/78705536一、dup和dup2函数 这两个函数都可以来复制一个现有的文件描述符&#xff0c;他们的声明如下&#xff1a;#include <unistd.h>int dup(int fd);int dup2(int fd, int fd 2); 123 关于dup函数&#xff0c;当我…

C++ cin 实现循环读入

习惯了使用while(~scanf("%d",x)){}来实现循环读入&#xff0c;但是有时候使用泛型编程的时候就必须使用C中的cin&#xff0c;但是当我想要实现循环读入的时候却发现有些困难。 我们可以看一下下面这个简单的例子&#xff1a; #include <iostream>using name…

BFPTR算法详解+实现+复杂度证明

BFPTR算法是由Blum、Floyed、Pratt、Tarjan、Rivest这五位牛人一起提出来的&#xff0c;其特点在于可以以最坏复杂度为O(n)O(n)O(n)地求解top−ktop-ktop−k问题。所谓top−ktop-ktop−k问题就是从一个序列中求解其第k大的问题。 top−ktop-ktop−k问题有许多解决方法&#xff…

随机化快速排序+快速选择 复杂度证明+运行测试

对于快速排序和快速选择我之前的文章已经有详细的说明&#xff0c;需要了解的同学可以移步 传送门&#xff1a;快速排序&#xff5c;快速选择(BFPTR) 所谓随机化其实就是选择枢纽的时候使用随机数选择而已&#xff0c;实现起来很简单。但是我们使用随机数如何保证复杂度呢&am…

【Linux基础】Linux的5种IO模型详解

引入 为了更好的理解5种IO模型的区别&#xff0c;在介绍IO模型之前&#xff0c;我先介绍几个概念 1.进程的切换 &#xff08;1&#xff09;定义 为了控制进程的执行&#xff0c;内核必须有能力挂起正在CPU上运行的进程&#xff0c;并恢复以前挂起的某个进程的执行。即从用户…

计算机网络【五】广播通信+以太网

局域网的拓扑 广域网使用点到点通信 局域网使用广播通信 可以随意向网络中添加设备。 总线网星形网&#xff0c;使用集线器。现在多使用星形网络。环状网树形网 其中匹配电阻用来吸收总线上传播的信号。 共享通信媒体 静态划分信道 频分复用、时分复用、波分复用、码分复用…

聊聊Linux 五种IO模型

一篇《聊聊同步、异步、阻塞与非阻塞》已经通俗的讲解了&#xff0c;要理解同步、异步、阻塞与非阻塞重要的两个概念点了&#xff0c;没有看过的&#xff0c;建议先看这篇博文理解这两个概念点。在认知上&#xff0c;建立统一的模型。这样&#xff0c;大家在继续看本篇时&#…

操作系统【四】分页存储管理

连续分配方式的缺点&#xff1a; 固定分区分配&#xff1a;缺乏灵活性&#xff0c;产生大量的内部碎片&#xff0c;内存的利用率较低 动态分区分配&#xff1a;会产生许多外部碎片&#xff0c;虽然可以用紧凑技术处理&#xff0c;但是紧凑技术的时间代价较高 基本分页存储管理…

操作系统【五】分段内存管理+段页式内存管理

基本分段存储管理 与分页最大的区别&#xff1a;离散分配时所分配地址空间的基本单位不同 进程的地址空间&#xff1a;按照程序自身的逻辑关系划分为若干个段&#xff0c;每个段都有一个段名&#xff0c;每段从0开始编址 内存分配规则&#xff1a;以段位单位进行分配&#xff…

计算机网络【六】网络层协议

网络层负责在不同网络之间尽力转发数据包&#xff08;基于数据包的IP地址转发&#xff09;。不负责丢失重传&#xff0c;也不负责顺序&#xff08;每一个数据包都是单独选择路径&#xff09;。 可靠传输是由传输层实现。 网络设备和OSI参考模型 通过分层&#xff0c;屏蔽了…

计算机网络【3】网络层

主要任务时把分组从源端发送到目的端&#xff0c;为分组交换网上的不同主机提供服务。网络层传输单位是数据报 功能&#xff1a; 路由选择与分组转发&#xff08;最佳路径 &#xff09;异构网络互联拥塞控制 数据交换方式 电路交换&#xff1a;通信时延小、有序传输、没有冲…

Linux探秘之用户态与内核态

https://www.cnblogs.com/bakari/p/5520860.html 一、 Unix/Linux的体系架构 如上图所示&#xff0c;从宏观上来看&#xff0c;Linux操作系统的体系架构分为用户态和内核态&#xff08;或者用户空间和内核&#xff09;。内核从本质上看是一种软件——控制计算机的硬件资源&…

哈夫曼算法证明+哈夫曼编码译码程序实现

哈夫曼算法证明 哈夫曼算法是一种贪心算法&#xff0c;我们考虑证明其最优子结构和贪心选择性质&#xff1a; 最优子结构&#xff1a;假设一个树是哈夫曼树&#xff0c;则以其任意节点为根节点的最大子树也是哈夫曼树。 证明&#xff1a;子树的根节点的值是其所有叶子节点出现…

Python3小知识

对于迭代器对象&#xff0c;Python默认赋值是将引用赋值&#xff0c;即指向同一片内存空间。为了实现对内存空间的赋值&#xff0c;我们可以使用分片进行深复制。例如&#xff1a; 当定义元组的时候&#xff0c;我们一般使用小括号将元素包围起来&#xff0c;也可以不使用括号…

汇编:实现日历星期数查询工具

编制一个简单日历查询工具&#xff0c;输入年、月、日&#xff0c;能够判断当日的星期数&#xff0c;并进行输出&#xff0c;数据的输入和结果的输出要有必要的提示&#xff0c;且提示独占一行。 查阅资料 ​ 经过查阅资料&#xff0c;发现有两个相关的算法可以解决这个问题&…