计算机操作系统-内存(1)定义、内存管理

  • 内存定义、作用

内存是用于存放数据的硬件。程序执行前需要先放到内存中才能被CPU处理。内存实际上就是一个用于存储数据的硬件,但是要区别于外存。内存的读取速度更快,从而能与CPU的速度完成匹配,如果是用外存,则访问速度无法与CPU相匹配。

作用1 进程的运行原理-指令

进程实体包括了PCB、数据段、程序段。指令包括了操作码,告诉CPU要做什么样的操作。这些指令都存放在内存的程序段中。 

我们写的代码要翻译成CPU能识别的指令。这些指令会告诉CPU应该去内存的哪个地址存/取数据。在实际生产机器指令时,往往并不知道进程的数据会被放到哪个位置,所以在指令中不会使用数据实际存放的地址。在编译生产的指令中一般使用的是逻辑地址(相对地址)

逻辑地址&物理地址

假设有N个指令,且知道当中第一个指令的物理地址,那么就可以在该地址上+N就可以得到其他N-1个指令的物理地址,所以只需要存储逻辑地址即可

作用2 从写程序到程序运行的过程

程序员-编辑→多个源代码文件-编译→多个目标模块-链接→1个装入模块→装入内存中

  • 编译

由编译程序将用户源代码翻译成若干个目标模块,编译就是将高级语言翻译为机器语言

  • 链接

由链接程序将编译后形成的一组目标模块,以及所需要的库函数链接在一起,形成一个完整的装入模块

  • 目标模块

相当于是由对应的源代码翻译得到的一系列的指令的集合。各个目标模块中的指令拥有的都是逻辑地址,且各个目标模块相互独立

  • 装入模块

经过链接程序,将各个目标模块链接起来得到的指令的集合,即为装入模块。装入模块具有一个完整的逻辑地址

  • 装入内存中

装入模块放入内存中运行,装入模块在内存中所具有的是物理地址,不再是逻辑地址

扫描二维码关注公众号,回复: 4978266 查看本文章

装入的三种方式(三种不同的方法完成逻辑地址到物理地址的转换)

在装入内存的指令中会有相应操作的对应地址

  • 绝对装入

在编译时,如果知道程序将放到内存中的哪个位置,编译程序将产生绝对地址的目标代码,装入程序按照装入模块的地址,将程序和数据装入内存。即指令集中的第一个地址是已知的,那么根据逻辑地址就可以知道物理地址。但是这种方式只适用于单道程序环境,因为如果是非单道程序环境,内存中存放的不止一个程序,这样对所有的程序约定该在哪个位置存放不现实

  • 静态重定位

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

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

  • 动态重定位

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

这个重定位寄存器是用于存放装入模块在内存中存放的起始位置的。根据重定位寄存器的值,在实际运行该程序时,对程序内的指令中的地址相加上重定位寄存器的值。所以这种方式是允许程序在内存中发生移动的,因为只需要修改重定位寄存器中存放的值,就可以得到指令中的逻辑地址对应更新后的物理地址。且这种方式还有诸多的优点:可将程序分配到不连续的存储区中;在程序运行前只需要装入它的部分代码即可投入运行,然后在程序运行期间,根据需要动态地申请分配内存;便于程序段的共享,可以向用户提供一个比存储空间大得多的地址空间。

链接的三种方式

  • 静态链接

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

  • 装入时动态链接

将各目标模块装入内存时,采用边装入边链接的链接方式

  • 运行时动态链接

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

  • 内存管理的概念

操作系统作为系统资源的管理者,必然要对内存进行管理

  • 操作系统负责内存空间的分配与回收

需要解决这些问题:操作系统要怎么记录哪些内存区域已经被分配出去了,哪些区域是空闲的;当内存中有很多位置可以存放,应该放在什么地方;当进程运行结束之后,如何将进程占有的内存空间回收…

  • 操作系统需要提供某种技术从逻辑上对内存空间进行扩充

将物理上很小的内存,拓展成逻辑上很大的内存。虚拟性

  • 操作系统需提供地址转换功能,负责程序的逻辑地址和物理地址的转换

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

  • 操作系统需要提供内存保护功能。

保证各进程在各自存储空间内运行、只能访问属于自己的内存空间。不能访问其他进程的内存空间,不能访问操作系统的内存空间,互不干扰

操作系统负责内存空间的分配与回收

连续分配管理方式

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

  • 单一连续分配

会将内存分为系统区和用户区。系统区用于存放操作系统相关数据;用户区用于存放用户进程相关数据。但是只能有一道用户程序,其独占整个用户区空间。无外部碎片,但是有内部碎片。所谓内部碎片,就是分配给某个进程的内存区域中,有些部分没有用上,那就是内部碎片。

  • 固定分区分配

为了能在内存中装入多道程序,且这些程序之间不会相互干扰,于是将整个用户空间划分为若干个固定大小的分区,在每个分区中只装入一道作业。可以根据分区大小是否相等对其进行分类

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

优点是无外部碎片,但是会产生内部碎片。且当程序太大时,可能所有分区都不能满足需求,那么此时不得不采用覆盖技术来解决,但是又会降低性能

  • 动态分区分配

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

  1. 操作系统中常用空闲分区表和空闲分区链来记录内存的使用情况
  2. 把一个新作业装入内存时,须按照一定的动态分区分配算法,从空闲分区表或空闲分区链中选出一个分区分配给该作业。
  3. 当对内存进行分配和回收时,需要对相应的空闲分区表或链的相关信息进行更新。注意当对内存进行回收时,需要将两个相邻的空闲分区进行合并

动态分区分配没有内部碎片,但有外部碎片

  • 内部碎片

分配给某个进程的内存区域中,没有用上的那些部分

  • 外部碎片

是指内存空间中某些空闲分区由于太小了而难以使用,因为是动态分配的方式,所以剩下的空闲空间大小是无法控制的。所以为了解决这个问题,可以采用拼凑技术。如果内存中空闲空间的总和可以满足某进程的要求,但是由于进程需要的是一整块连续的内存空间,而这些碎片不能满足进程的要求,所以才用拼凑技术

非连续分配方式

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

支持多道程序的两种连续分配方式:固定分区分配、动态分区分配

这两种方式都会分别留下内部碎片和外部碎片的缺点

带来这些缺点的原因,就是以上的分配方式都有给一个进程分配的需要是整块完整的内存空间的前提,那么自然而然就会想到,是不是可以将一个进程分散地装入许多不相邻的分区中,以便能够充分地利用内存,而不需要再使用动态分区分配和采用”紧凑”技术。所以基于这种思想,产生了非连续分配方式,或者称为离散分配方式

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

基本分页存储管理的思想:把内存分为一个个相等的小分区,再按照分区大小把进程拆分成一个个小部分

将内存空间分为一个个大小相等的分区,每个分区就是一个页框(页帧、内存块、物理块),每一个页框都有一个编号,即页框号。页框号从0开始

将用户进程的地址空间也分为与页框大小相等的一个个区域,称为页或者页面。每一个页面都有一个编号,即页号,也是从0开始的。因为进程的最后一个页面可能没有一个页框那么大,因此页框不能设置得太大,否则可能产生过大的内部碎片

操作系统会以页框为单位为各个进程分配内存空间。进程的每个页面分别放入一个页框中,也就是说,进程的页面与内存的页框有一一对应的关系

各个页面不必连续存放,也不必按先后顺序来,可以放到不相邻的各个页框中

内存扩充的技术

  • 覆盖技术
  • 交换技术
  • 虚拟存储技术

覆盖技术

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

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

内存中会分为一个固定区和若干个覆盖区。需要常驻内存的段放在固定区中,调入后就不再调出(除非运行结束)。不常用的段放在覆盖区中,需要用到时调入内存,用不到时调出内存。

实际中,按照程序自身的逻辑结构,让那些不可能同时被访问的程序段共享同一个覆盖区。且程序的调用结构,必须由程序员声明,声明覆盖结构后,操作系统完成自动覆盖。这样存在一个缺点,就是对用户不透明,增加了用户编程负担

交换技术

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

中级调度就是为了实现交换技术的调度方式,通过挂起队列中的PCB来对这些进程进行管理。所以中级调度就是要决定将哪个处于挂起状态的进程重新调入内存。暂时换出外存等待的进程为挂起状态

猜你喜欢

转载自blog.csdn.net/weixin_39721347/article/details/86533701