第三章 内存管理

内存管理

内存管理概念

操作系统对内存的划分和动态分配。

内存管理的基本原理和要求

内存的主要功能:

  • 内存空间的分配与回收: 有操作系统完成主存储器空间的分配和管理
  • 地址转换: 在多道程序环境下,程序中的逻辑地址与内存中的物理地址不可能一致,因此内存管理必须提供地址交换功能,把逻辑地址转换成相应的物理地址
  • 内存空间的扩充: 利用虚拟存储技术活自动覆盖技术,从逻辑上扩充内存
  • 内存共享: 指允许多个进程访问内存的同一部分
  • 存储保护: 保证各道作业在各自的存储空间内运行,互不干扰

进程运行的基本原理和要求:

1.程序的链接与装入
创建程序首先要将程序和数据装入内存。将用户源程序变为可在内存中执行的程序,通常需要以下几个步骤:

  • 编译: 将用户源代码编译成若干目标模块
  • 链接: 将编译后形成的一组目标模块及它们所需的库函数链接在一起,形成一个完整的装入模块
  • 装入: 将装入模块装入内存运行

在这里插入图片描述

程序的链接有以下三种方式:

  • 静态链接: 在程序运行之前,先将各目标模块及它们所需的库函数链接成一个完整的装配模块,以后不再拆开
  • 装入时动态链接: 将用户源程序编译后所得到的一组目标模块,在装入内存时,采用边装入边链接的方式。其优点是便于实现对目标模块的共享。
  • 运行时动态链接: 对某些目标模块的链接,是在程序执行中需要该目标模块时才进行的。凡在执行过程中未被用到的目标模块都不会被调入内存和被链接到的。其优点是能加快程序的装入过程,还可以节省大量的内存空间。

内存调装入模块在装入内存时,同样有以下三种方式:

  • 绝对装入: 绝对装入只适用于单道程序环境。绝对装入程序按照装入模块中的地址将程序和数据装入内存。程序中所用的绝对地址,可在编译或汇编时给出,也可由程序员直接赋予。而通常情况下在程序中采用的是符号地址,编译或汇编时再转换为绝对地址。

  • 可重定位装入: 在多道程序环境下,多个目标模块的起始地址通常都从0开始,程序中的其他地址都是相对于起始地址的,此时应采用可重定位装入方式。

  • 动态运行时装入: 程序在内存中若发生移动,则需要采用动态的装入方式,装入程序把装入模块装入内存后,并不立即把装入模块中的相对地址转换为绝对地址,而是把这种地址转换推迟到程序真正要执行时才进行。

    动态重定位的优点: 可以将程序分配到不连续的存储区;在程序运行之前可抑制装入部分代码,即可投入运行,然后在程序运行期间,更有需要动态申请分配内存;便于程序段的共享。

2.逻辑地址与物理地址

逻辑地址: 编译后,每个目标模块都从0号单元开始编址,这称为目标模块的相对地址。

物理地址: 计算机内存中的实际地址,计算机硬件直接访问内存的地址,用于唯一标识内存中的每个存储单元。

3.进程的内存映像

当一个程序调入内存运行时,就构成了进程的内存映像。一个进程的内存映像一般有几个要素:

  • 代码块: 程序的二进制代码,代码段时只读的,可被多个进程共享
  • 数据块: 程序运行时加工处理的对象,包括全局变量和静态变量
  • 进程控制块(PCB): 存放在系统区。操作系统通过PCB来控制和管理进程
  • 堆: 用来存放动态分配的变量。通过调用malloc函数动态地向搞地质分配空间
  • 栈: 用来实现函数调用。从用户空间的最大地址往低地址方向增长

4.内存保护

内存分配前,需要傲虎操作系统不受用户进程的影响,同时保护用户进程不受其他用户进程的影响。内存保护可采取两种方法:

(1)在CPU中设置一对上、下限寄存器,存放用户作业在主存中的下限和上限地址,内档CPU要访问一个地址使,分别和两个寄存器的值相比,判断有无越界

(2)采用重定位寄存器(又称基地址存储器)和界地址(又称限长寄存器)来实现这种保护

覆盖与交换

(1)覆盖

覆盖的基本思想: 由于程序运行时并非任何时候都要访问程序及数据的各个部分,因此可把用户控件分成一个固定区和若干覆盖区。将经常活跃的部分放在固定区,其余部分按调用关系分段。首先将那些即将要访问的段放入覆盖区,其他段放在外存中,在需要调用前,系统再将其调入覆盖区,替换覆盖区中原有的段。

覆盖技术的特点: 打破必须将一个进程的全部信息装入主存后才能运行的限制,但当同时运行程序的代码量大于主存时仍不能运行,此外,内存中能够更新的地方只有覆盖区的段,不在覆盖区中段会常驻内存。覆盖技术对用户和程序员不透明。

(2)交换

交换的基本思想: 把处于等待状态(火灾CPU调度原则下被剥夺运行权利)的程序从内存移到辅存,把内存空间腾出来,这一过程又称换出;把准备好竞争CPU运行的程序从辅存移到内存,这一过程称为转入

关于交换需注意以下几点:

  • 交换需备份存储,通常是磁盘,足够大,并提供对这些内存映像的直接访问
  • 为了有效使用CPU,需要是每个进程的执行时间比交换时间长
  • 若换出进程,则必须确保该进程完全处于空闲状态
  • 交换空间通常作为磁盘的一整块,且独立于文件系统,因此使用起来可能很快
  • 交换通常在有许多进程进行且内存空间紧张时开始启动,而在系统负荷降低时就暂停
  • 普通的交换使用不多,单交换策略的某些变体在许多系统重仍发挥作用

连续分配管理方式

连续分配方式是指为一个用户程序分配一个连续的内存空间

1.单一连续分配

内存在此方式下分为系统区和用户区,系统区仅供操作系统使用,通常在地址地址部分;在用户区内存中,仅有一道用户程序,即整个内存的用户空间由该程序独占

优点:简单、无外部碎片,无序进行内存保护,因为内存中永远只有一道程序

缺点:只能用于单用户、单任务的操作系统中,有内部碎片,存储器的利用率极低

2.固定分区分配

将用户内存空间划分若干固定大小区域,每个分区只能装入一道作业。当空闲分区时,便可再从外存的后备作业队列中选择适当大小的作业装入该分区,如此循环。在划分分区时有两种不同的方法。

  • 分区大小相等。程序太小会造成浪费,程序太大又无法装入,缺乏灵活性
  • 分区大小不等。划分为多个较小的分区、适量的中等分区和少量大分区

在这里插入图片描述

为方便内存分配,通常将分区按大小排队,并为之建立一张分区说明表,其中各表项包括每个分区的始址、大小及状态,示例如下:

在这里插入图片描述

3.动态分区分配

又称可变分区分配,它是在进程装入内存时,根据进程的实际需要,动态地为之分配内存,并使分区的大小正好适合进程的需要。因此,系统中分区的大小和数目是可变。

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

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

外部碎片,是指内存中的某些空闲分区由于太小而难以利用

由于进程需要的是一整块连续的内存空间,因此这些“碎片”不能满足进程,但可以通过紧凑技术来解决外部碎片

在这里插入图片描述

动态分区分配算法

首次适应算法(First Fit)

空闲分区以地址递增的次序链接。分配内存时,从链首开始顺序查找,找到大小能满足要求的第一个空闲分区分配给作业
在这里插入图片描述

最佳适应算法(Best Fit)

空闲分区按容量递增的次序形成空闲分区链,找到一个能满足要求且最小的空闲分区分配给作业
在这里插入图片描述

最坏适应算法(Worst Fit)

空闲分区以容量递减的次序链接,找到第一个能满足要求的,即最大的分区,从中分割一部分存储空间给作业

在这里插入图片描述

邻近适应算法(Next Fit)

由首次适应算法演变而成。不同之处是,分配内存时从上次查找结束的位置开始继续查找

在这里插入图片描述
在这里插入图片描述

基本分页存储管理

把主存空间划分为大小相等且固定的块,块相对较小,作为主存的基本单位。每个进程也以块为单位进行划分,进程在执行时,以块为单位逐个申请主存中的块空间,每个进程平均只产生半个块大小的内部碎片(也称页内碎片)

在这里插入图片描述

分页存储的几个基本概念

1.页面和页面大小

进程中的块称为页或页面,内存中的块称为页框或页帧。外存也以同样的单位进行划分,直接称为块或盘块。

2.地址结构

地址结构包含两部分:前一部分为页号P,后一部分为页内偏移量W。地址长度为32位.其中0~11位为页内地址,即每页大小为4KB;12~31位为页号,即最多允许2的20次方页。

注意:地址结构决定了虚拟内存的寻址空间有多大

3.页表

为方便在内存中找到进程的每个页面所对应的物理块,系统为每个进程建立一张页表,它记录页面在内存中对应的物理块号,页表一般存放在内存中,在配置页表后,进程执行时,通过查找该表,即可找到每页在内存中的物理块号

拓展:

每个页表项所占字节大小
在这里插入图片描述

地址转换的过程
在这里插入图片描述

逻辑地址对应的页号、页内偏移量
在这里插入图片描述
在这里插入图片描述

基本地址变换机构

地址变换机构的任务是将逻辑地址转换为内存中的物理地址。地址变换是借助于页表实现的。
在这里插入图片描述

在系统中通常设置一个页表寄存器(PTR),存放页表在内存的起始地址F页表长度M。在进程未执行时,页表的始址和页表长度存放在本进程的PCB中,当进程被调度执行时,才将页表始址和页表长度装入页表寄存器中。设页面大小为L逻辑地址A物理地址E的变换过程如下(假设逻辑地址、页号、每页的程度都是十进制数):

  • 计算页号P(P=A/L)页内偏移量W(W=A%L)
  • 比较页号P页表长度M,若P>=M则产生越界中断,否则继续执行
  • 页表中页号P对应的页表项地址=页表始址F+页号P*页表项长度,取出该页表项内容b,即为物理块号。注意区分页表长度和页表项长度。页表长度是指一共有多少页,页表项长度是指页地址占多大的存储空间
  • 计算E=b*L+W,用得到的物理地址E去访问内存
    在这里插入图片描述
    在这里插入图片描述
具有快表的地址变换机构

快表:又称联想寄存器(TLB),是一种访问速度比内存快很多的告诉缓存,用来存放最近访问的页表项的副本,可以加速地址变换的速度

在这里插入图片描述

在具有快表的分页机制中,地址的变换过程如下:

  • CPU给出逻辑地址后,由硬件进行地址转换,将页号送入高速缓存寄存器,并将此页号与快表中的所有页号进行比较
  • 若找到匹配的页号,说明所要访问的页表项在快表中,则直接从中取出该页对应的页框号,与页内偏移量拼接形成物理地址。这样,存取数据仅一次访存便可实现
  • 若未找到匹配的页号,则需要访问主存中的页表,读出页表项后,应同时将其存入快表,以便后面可能的再次访问。若快表已满,则须按特定的算法淘汰一个旧页表项

基本地址变换机构与具有快表的地址变换机构对比如下:

在这里插入图片描述

两级页表

将长长的页表进行分组,使每个内存块刚好可以一个分组(如页面大小4KB,每个页表项4B,每个页面可存放1K页表项,因此每1K个连续的页表项为一组,每组刚好占一个内存块,在将各组离散地放到各个内存块中),另外,为离散分配的页表再建立一张页表,称为页目录表,或称为外层页表,或称顶层页表

两级页表的原理、地址结构如下:
在这里插入图片描述
在这里插入图片描述

实现地址转换的过程:
在这里插入图片描述

需注意的细节:

1.若采用多级页表机制,则各级页表的大小不能超过一个页面

2.两级页表的访存次数分析(假设没有开标机构)

第一次访存:访问内存中的页目录表

第二次访存:访问内存中的二级页表

第三次访存:访问目标内存单元

在这里插入图片描述

基本分段存储管理

分页管理方式是从计算机的角度设计的,目的是提高内存的利用率,提升计算机的性能。分页通过硬件机制实现,对用户完全透明。分段管理方式的提出则考虑了用户和程序员,以满足方便编程、信息保护和共享、动态增长及动态链接等多方面的需要

分段

进程的地址空间:按照程序自身的逻辑关系划分为若干个段,每个段都有一个段名(在低级语言中,程序员使用段名来编程),每段从0开始编址

内存分配规则:以段为单位进行分配,每个段在内存中占据连续空间,但各段之间可以不相邻

分段系统的逻辑地址结构由段号(段名)和段内地址(段内偏移量所组成)

在这里插入图片描述

段表

每个进程都有一张逻辑空间与内存空间映射的段表,其中每个段表项对应进程的一端,段表项记录该段在内存中的始址和长度

在这里插入图片描述

地址变换机构

为实现进程从逻辑地址到物理地址的变换功能,在系统中设置了段表寄存器,用于存放段表始址F和段表长度M。从逻辑地址A物理地址E之间的地址变换过程如下:
在这里插入图片描述

分段、分页管理的对比

页是信息的物理单位。分页的主要目的是为了实现离散分配,提高内存利用率。分页仅仅是系统管理上的需要,完全是系统行为,对用户是不可见的

段是信息的逻辑单位。分段的主要目的是更好地满足用户需求。一个段通常包含一组属于一个逻辑模块的信息。分段对用户是可见的,用户编程时需要显示地给出段名

页的大小固定且由系统决定。段的长度不固定,决定于用户编写的程序

分页的用户进程地址空间是一维的,程序员只需给出一个记忆符即可表示一个地址

分段的用户进程地址空间是二维的,程序员在标识一个地址时,既要给出段名,也要给出段内地址

分段比分页更容易实现信息的共享和保护。不能被修改的代码称为纯代码或可重入代码,这样的代码是可以共享的,可修改的代码是不能共享的

访问一个逻辑地址需要几次访存?
分页(单机页表):第一次访存——查内存的页表,第二次访存——访问目标内存单元。总共两次访存
分段:第一次访存——查内存的段表,第二次访存——访问目标内存单元。总共两次访存

在这里插入图片描述

段页式管理

在段页式系统中,作业的地址空间首先被分成若干逻辑段,每段都有自己的段号,然后将每段分成若干大小固定的页。对内存空间的管理仍然和分页存储管理一样,将其分成若干和页面大小相同的存储块,对内存的分配以存储块为单位

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

虚拟存储管理

虚拟内存的基本概念

传统存储管理方式的特征
  • 一次性: 作业必须一次性全部装入内存后才能开始运行。这会造成两个问题:(1)作业很大时,不能全部装入内存,导致大作业无法运行;(2)当大量作业要求运行时,由于内存无法容纳所有作业,因此只有少量作业能运行,导致多道程序并发度下降
  • 驻留性: 一旦作业被装入内存,就会一直驻留在内存中,直至作业运行结束。事实上,在一个时间段内,只需要访问作业的一小部分数据即可正常运行,这就导致内存中会驻留大量的、暂时用不到的数据,浪费了宝贵的内存资源
局部性原理
  • 时间局部性: 如果执行了程序中某条指令,你那么不久后这条指令很可能再次执行;如果某个数据被访问过,不久之后数据很可能再次被访问
  • 空间局部性: 一旦程序访问了某个存储单元,子啊不久之后,其附近的存储单元也很有可能被访问
虚拟存储的定义和特征

基于局部性原理,在程序装入时,可以将程序中很快用到的部分装入内存,暂时用不到的部分留在外存,就可让程序开始执行

在程序执行过程中,当所访问的信息不在内存时,由操作系统负责将所需信息从外存调入内存,然后继续执行程序

若内存空间不够,由操作系统负责将内存中暂时用不到的信息换出到外存

在操作系统的管理下,在用户看来似乎有一个比实际内存大得很多的内存,这就是虚拟内存

虚拟内存有以下三个主要特征:

  • 多次性: 无需在作业运行时一次性全部装入内存,而是允许被分成多次调入内存
  • 对换性: 在作业运行时无需一致常驻内存,而是允许在作业运行过程中,将作业换入、换出
  • 虚拟性: 从逻辑上扩充了内存的容量,使用户看到的内容容量,远大于实际容量
虚拟内存技术的实现

虚拟内存技术,允许一个作业分多次调入内存。如果采用连续分配方式,会不方便实现。因此,虚拟内存的实现需要建立在离散分配的内存管理方式基础上

虚拟内存的实现有以下三种方式:

  • 请求分页存储管理
  • 请求分段存储管理
  • 请求段页式存储管理

传统的非连续分配存储管理和虚拟内存的实现的主要区别:
在程序执行过程中,当所访问的信息不在内存时,由操作系统负责将所需信息从外存调入内存,然后继续执行程序(操作系统要提供请求调业/请求调段功能)

若内存空间不够,由操作系统负责将内存中暂时用不到的信息换出到外存(操作系统要提供页面置换/段置换的功能)

在这里插入图片描述

请求分页管理方式

在请求分页系统中,只要求当前需要的一部分页面装入内存,便可以启动作业运行。在作业执行过程中,当所要访问的页面不在内存中时,再通过调页功能将其调入,同时还可通过置换功能将暂时不用的页面换出外存上,以便腾出内存空间

为了实现请求分页,系统必须提供一定的硬件支持。除了需要一定容量的内存及外存的计算系统,还需要有页表机制、缺页终端机构好地址变换机构。

页表机制

在这里插入图片描述

缺页中断机构

在这里插入图片描述
在这里插入图片描述

地址变换机构

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

页面置换算法

最佳(OPT)置换算法

每次选择淘汰的页面讲师以后永不使用,或者在最长时间内不再被访问的页面,这样可以保证最低的缺页率,但实际上,只有在进程细心的过程中才能知道接下来会访问到时哪个页面。操作系统无法提前预判页面访问序列。因此,最佳置换算法是无法实现的

在这里插入图片描述

先进先出(FIFO)页面置换算法

每次选择淘汰的页面是最早进入内存的页面
在这里插入图片描述

最近最久未使用(LRU)置换算法

选择最近最长时间未访问过的页面予以淘汰,它认为过去一段时间内为访问过的页面,在最近的将来可能也不会被访问
在这里插入图片描述

时钟(CLOCK)置换算法

时钟置换算法:
在这里插入图片描述

改进型的时钟置换算法:
在这里插入图片描述
在这里插入图片描述

页面分配策略

  • 驻留集: 请求分页存储管理中给进程分配的物理块的集合

    在采用了虚拟存储技术的系统中,驻留集大小一般小于进程的总大小

    若驻留集太小,会导致缺页频繁,系统要花大量时间来处理缺页,实际用于进程推进的时间很少

    驻留集太大,又会导致多道程序并发度下降,资源利用率降低,所以应选择一个合适的驻留集大小
  • 固定分配: 操作系统为每个进程分配一组固定数目的物理块,在运行期间不再改变。即驻留集大小不变
  • 可变分配: 先为每个进程分配一定数目的物理块,在进程运行期间,可根据情况做适当的增加或减少。即驻留集大小可变
  • 局部置换:发生缺页只能选进自己的物理块进行置换
  • 全局置换:可以将操作系统保留的空闲物理块给缺页进程,也可以将别的进程持有的物理块置换到外存,再分配给缺页进程

固定分配局部置换: 系统为每个进程分配一定数量的物理块,在整个运行期间都不改变。若进程在运行中发生缺页,则只能从该进程在内存中的页面中选出一页换出,然后再调入需要的页面

此策略的缺点:很难再刚开始就确定应为每个进程分配多少个物理块才算合理

可变分配全局置换: 刚开始会为每个进程分配一定数量的物理块。操作系统会保持一个空闲物理块队列。当某进程发生缺页时,从空闲物理块中取出一块分配给该进程;若无空闲块,则可选择一个未锁定的页面换出外存,再将该物理块分配给缺页的进程。采用这种策略时,只要某进程发生缺页都将获得新的物理块,仅当空闲物理块用完时,系统才选择一个未锁定的页面调出。被选择调出的也可能是系统中任何一个进程中的页,因此这个被选中的进程拥有的物理块会减少,缺页率会增加

可变分配局部置换: 刚开始会为每个进程分配一定数量的物理块。当某进程发生缺页时,只允许从该进程自己的物理块中选出一个进行换出外存。如果进程在运行中频繁地缺页,系统会为该进程分配几个物理块,直至该进程缺页率趋势适当程度;反之,如果进程在运行中缺页率特别低,则可适当减少分配给该进程的物理块

可变分配全局置换:只要缺页就给分配新物理块
可变分配局部置换:要根据发生缺页的频率来动态地增加或减少进程的物理块

调入页面的策略
  • 预调页策略: 根据局部性原理,一次调入若干个相邻的页面可能比一次调入一个页面更高效。但如果提前调入的页面中大多数都没被访问过,则又是低效的。因此可以预测不久之后可能访问到页面,将它们预先调入内存,但目前预测成功率只有50%左右。固这种策略主要用于进程的首次调入
  • 请求调页策略:进程在运行期间发现缺页时才将所缺页面调入内存。有这种策略调入的页面一定会被访问到,但由于每次只能调入一页,而每次调页都要磁盘I/O操作,因此I/O开销较大
调入页面的地方

1.系统拥有足够的对换空间:页面的调入、调出都是在内存与兑换区之间进行,这样可以保证页面的调入、调出速度很快。在进程运行前,需将进程相关的数据从文件区复制到对换区

2.系统缺少足够的对换空间:凡是不会被修改的数据都直接从文件区调入,由于这些页面不会被修改,因此换出时不必写回磁盘,下次需要时再从文件区调入即可。对于可能被修改的部分,换出时需写回磁盘对换区,下次需要时再从对换区调入

3.UNIX方式:运行之前进程有关的数据全部放在文件区,故未使用过的页面,都可从文件区调入。若被使用过的页面需要换出,则写回对换区,下次需要时从对换区调入

抖动现象

刚刚换出的页面马上又要换入内存,刚刚换入的页面马上又要换出外存,这种频繁的页面调度行为称为抖动。产生抖动的主要原因是进程频繁访问的页面数目高于可用的物理块数(分配给进程的物理块不够)

工作集

指在某段时间间隔里,进程实际访问页面的集合

工作集大小可能小于窗口尺寸,实际应用中,操作系统可以统计进程大小,根据工作集大小给进程分配若干内存块。

一般来说,驻留集带下不能小于工作集大小,否则进程运行过程中将频繁缺页。

在这里插入图片描述

内存映射文件

内存映射文件的特性
  • 进程可使用系统调用,请求操作系统将文件映射到进程的虚拟地址空间
  • 以访问内存的方式读写文件
  • 进程关闭文件时,操作系统负责将文件数据写回磁盘,并解除内存映射
  • 多个进程可以映射同一个文件,方便共享
内存映射文件的优点
  • 程序员编程更简单,已建立映射的文件,只需按访问内存的方式读写即可
  • 文件数据的读入/写出完全由操作系统负责,I/O效率可以由操作系统负责优化
  • 11
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值