操作系统(四)| 内存管理 实存储器管理 虚拟存储器管理 分页 分段式管理

文章目录

  • 1 内存管理概述
    • 1.1 内存管理目的
    • 1.2 内存管理功能
  • 2 程序的连接和装入
    • 2.1 程序的连接
      • 2.1.1程序的连接的功能
      • 2.1.2 程序连接的时机
    • 2.2 程序的装入
      • 2.1.1 完全静态装入
      • 2.1.2 静态重定位装入
      • 2.1.3 动态重定位装入
  • 3 实存储器管理
    • 3.1 连续分配
      • 3.1.1 单一连续分配
      • 3.1.2 固定分区
      • 3.1.3 可变分区
    • 3.2 离散分配
      • 3.2.1 分页管理
      • 3.2.2 分段管理
      • 3.2.3 分页分段管理
  • 4 虚拟存储管理
    • 4.1 分页+虚拟存储
      • 4.1.1 页的换入换出
      • 4.1.2 页的置换算法
    • 4.2 分段+虚拟存储
    • 4.3 段页+虚拟存储

1 内存管理概述

内存是存储系统的一部分

存储系统核心目的是存储要运行的程序数据之类的

存储系统的设计目标可以归纳为3个问题

容量,速度,和成本之间的矛盾:

​ 三个目标不可能同时达到最优,要权衡利弊

​ 存取速度越快,每一位价格越高

​ 大容量就要降低速度

​ 高速度就要降低容量

解决方案:采用层次化的存储体系

换句话说 靠近CPU的,我们把他的存取速度加大,同时他的成本就会增加,容量就会减少

寄存器(CPU内)-》高速缓冲(Cache)-》内存-》磁盘-》磁带

从左到右,存取速度下降,存取容量增大

1.1 内存管理目的

​ 有效利用内存空间

​ 应用程序不必特别考虑内存的大小

​ 可以大于内存

1.2 内存管理功能

​ 记录内存的使用情况

​ 进程所占内存空间的分配与回收

​ 当内存不足时,采取相应措施

​ 内存空间的共享与保护

2 程序的连接和装入

2.1 程序的连接

2.1.1程序的连接的功能

多个目标文件及库文件连接成1个完整的可执行文件。

2.1.2 程序连接的时机

静态连接:静态的,只连接1次,多次运行
装入时连接:装入后是静态的
实际运行时连接:调用时动态连接

2.2 程序的装入

每个程序运行前,必须装入内存(为什么?这样存取速度才能匹配上CPU的速度)不一定一次性全部装入

装入方式有

2.1.1 完全静态装入

程序装入时不作任何修改。
即装入内存的每个字节与其可执行文件完全相同。

2.1.2 静态重定位装入

程序装入时进行一次地址重定位,运行时不变。

重定位是把汇编中的相对地址转换为内存中的实际地址

相对地址:
用户的程序经过汇编或编译连接后形成可执行代码,代码通常采用相对地址的形式,其首地址为0,指令中的地址都采用相对于首地址的偏移量。
机器是不能用相对地址在内存中读取信息的,必须用绝对地址
绝对地址:
内存中存储单元的实际地址

2.1.3 动态重定位装入

真正执行到一条指令要访问某个内存地址时,才进行地址重定位。

一般设置1个重定位寄存器 存放当前进程在内存的起始地址
绝对地址 = 相对地址 + 重定位寄存器的值

3 实存储器管理

程序的大小不能超过可用内存空间的大小

实实在在的 给我装进去哈哈哈

3.1 连续分配

为每个进程分配连续的内存空间

3.1.1 单一连续分配

内存中只存在1个用户程序。
整个用户区为该程序独占。

一般将内存划分为2个区:
系统区:存放OS程序和数据
用户区:存放用户程序和数据

缺点:

只能用于单用户、单任务OS。

3.1.2 固定分区

将内存的用户区预先划分为若干区域(分区)
分区个数和每个分区的大小是固定的
每个分区存放1个进程

​ 缺点:

(1) 超过最大分区的程序无法装入;
(2) 存在内部碎片(Internal fragmentation):
(3) 分区数目固定,使活动进程数目受限;

3.1.3 可变分区

动态分区。
开始时只有1个空闲分区,随着进程的装入和退出,分区的个数和每个分区的大小、位置会动态变化。

需要的记录的数据结构

1 空闲分区表 记录开始地址,长度,以及状态(是否分配)

2 已分配分区表 记录开始地址,长度,以及进程号

分区分配算法

① 最先适配法(first fit)
空闲分区链(表)按地址递增的次序排列
从头开始,选择第1个大小足够的分区

② 下次适配法(next fit)
从上次分配的分区的下一个开始,选择第1个大小足够的分区

③ 最佳适配法(best fit)
空闲分区链(表)按大小递增的次序排列
从头开始,选择第1个大小足够的分区

④ 最差适配法(worst fit)
空闲分区链(表)按大小递减的次序排列
从头开始,选择第1个分区(如果足够大)

分区的回收

将回收的分区插入到空闲分区链(表)的合适位置
合并相邻的多个空闲分区
考虑:上邻、下邻、上下相邻、上下不相邻

存在一个问题:外部碎片

如何解决

1 内存紧凑(compaction):集中小碎片为大分区 但是涉及到程序在内存中的移动,开销很大

2 根本上是因为 连续分配,所以从根本上解决,提出离散分配

3.2 离散分配

3.2.1 分页管理

(1)等分内存为物理块(或称页面,页框,page frame)
物理块编号为0,1,2,...。
(2)进程的逻辑地址空间分页(page)
页大小 = 物理块大小
页编号为0,1,2,...。
(3)内存分配原则:
进程的1页可装入任一物理块

管理的数据结构

OS为每个进程建立1个页表(Page Table)
记录进程的页号和物理块号的对应关系

地址转换

(1)页表寄存器(Page Table Register, PTR)
系统设置1个页表寄存器,存放当前进程的页表起始地址和长度

​ 每个进程的页表起始地址和长度平时放在其PCB中,调度时由OS放入PTR

(2)页大小选择

页小:碎片小,但页表占用空间大
页大:页表小,但页内碎片大
通常,页的大小为2的整数次幂

(3)进程的逻辑地址结构 及地址转换
地址的高位部分为页号,低位部分为页内地址

物理地址 = 块号×页大小 + 页内地址

CPU要存取一个数据时,需要访问内存几次?

2次。
第1次:访问页表,找到该页对应的物理块号,将此块号与页内地址拼接形成物理地址;
第2次:访问该物理地址,存取其中的指令或数据。

(4)引入快表

快表,又称联想存储器(Associative Memory) :
具有并行查找能力的特殊高速缓存(cache)。

在x86系统中叫做TLB(Translation lookaside buffers)
用途:保存当前进程的页表的子集(部分表项),比如最近访问过的页表项。
当切换到新进程时,快表要刷新。

目的:提高地址转换速度

页表本身可能占用相当大的内存空间,而且是连续的。

如何解决

采用二级页表(只能解决连续,但解决不了占用较大的内存)

将页表进行分页,页大小 = 物理块大小
设置1个一级页表,多个二级页表
一级页表:第i项记录第i号二级页表所在的物理块号
二级页表:第i项记录第i页对应的物理块号
系统设置1个页表寄存器,存放一级页表的起始地址和长度

二级页表并未减少页表所占的内存空间,但解决了页表的离散分配问题。

3.2.2 分段管理

静态段式管理

按程序的逻辑划分为若干个程序段,每一个段连续,且各个段的长度不等

段号从0开始

分段类似于可变分区,但不同之处在于:
一个进程可占据多个分区,而且分区之间不要求连续。
分段无内部碎片,但有外部碎片。

(2)内存分配原则

以段为单位,各段不要求相邻

管理需要的数据结构

OS为每个进程建立1个段表(Segment Table)
每个段在段表中有1项,记录该段在内存中的基址和长度

分段分页比较

(1)分页对程序员是不可见的;分段通常是可见的,并作为组织程序和数据的手段提供给程序员;
(2)页的大小由系统确定,段的大小由用户程序确定;
(3)分段更利于多个进程共享程序和数据;
(4)分段便于实现动态链接;
(5)分页可有效提高内存利用率,分段可更好地满足用户需要。

3.2.3 分页分段管理

动机:结合分段和分页的优点,克服二者的缺点。

进程分段——同段式管理
每段分页,内存分块,内存以块为单位分配——同页式管理

进程的逻辑地址结构

由段号、页号和页内地址构成

每个进程有一个段表

记录每个段对应的页表的起始地址和长度

每个段有一个页表

记录该段所有页号与物理块的关系

CPU要存取一个数据时,需要访问3次内存。

实存储管理模式下,怎么提高运行程序的大小

覆盖

把程序划分为若干个功能上相对独立的程序段(称为覆盖块),按照其自身的逻辑结构使那些不会同时执行的程序段共享同一块内存区域;

覆盖块存放在磁盘上,当一个程序段执行结束,把后续程序段调入内存,覆盖前面的程序段(内存“扩大”了)

(1) 要求程序员划分程序,提供一个明确的覆盖结构;
(2) 增加了编程的复杂度
(3) 增加执行时间,从外存装入覆盖模块,时间换空间
对用户不透明,增加了用户负担。

所以更好的方式是虚拟存储管理

4 虚拟存储管理

进程的大小可以超过可用物理内存的大小,
由OS把当前用到的那部分留在内存,其余的放在外存中。

几个概念

虚拟地址:程序中使用的地址。进程的虚拟地址从0开始。
物理地址:可寻址的内存实际地址
虚拟地址空间:虚拟地址的集合
物理地址空间:实际的内存空间

交换技术

4.1 分页+虚拟存储

在进程开始运行之前,不是装入全部页,而是装入部分或0个页,之后根据进程运行的需要,动态装入其它页;
当内存空间已满,而又需要装入新的页时,则根据某种算法淘汰某个页,以便装入新的页。

除了页号和物理块号外,需要增加下列字段:

有效位(状态):表示该页是否在内存中
1 表示该页位于内存中,该页表项是有效的,可以使用
0表示该页当前在外存中,访问该页表项将导致缺页异常

修改位M:表示该页在装入内存后是否被修改过
在有效位为1的情况下有效的情况下
回收该物理页面时,据此判断是否要把它的内容写回外存

访问位A(访问字段):记录该页最近是否被访问过
用于页面置换算法

保护位:表示该页的允许访问方式
只读、可读写、可执行等

外存地址:该页在磁盘上的地址

4.1.1 页的换入换出

1)页的分配策略:为每个进程分配多少个物理块

固定分配
为每个进程分配的总物理块数固定,在整个运行期间不变。

可变分配
先为每个进程分配一定数目的物理块,OS自身维持一个空闲物理块队列。
当发生缺页时,由系统分配一个空闲块,存入调入的页;

2)页的置换策略:在什么范围内选择淘汰页
局部置换
只从缺页进程自身选择淘汰页
全局置换
从整个内存中选择淘汰页 当无空闲块时,才会换出。

3)页的调入策略
① 何时调入
请求调页(demand paging)
只有访问的页不在内存中时,才会调入该页。
预调页(prepaging)
一次调入多个连续的页。为什么这样做?
② 从何处调入:文件区(可执行文件)、交换区
全部从交换区调入
进程创建时,全部从文件区拷贝到交换区。
首次调入从文件区,以后从交换区

4)页的置换算法

选择换出页 减少缺页率

4.1.2 页的置换算法

最优置换算法

先进先出置换算法

最近最久未使用算法

LRU算法

最近未使用算法(NRU)

工作集置换算法

4.2 分段+虚拟存储

4.3 段页+虚拟存储

页式管理

相对物理块来说,页是逻辑地址空间(**虚拟内存**空间)的划分,是逻辑地址空间顺序等分而成的一段逻辑空间,并依次连续编号。页的大小一般为 512B~8KB。

例如:一个 32 位的操作系统,页的大小设为 2^12=4Kb,那么就有页号从 0 编到 2^20 的那么多页逻辑空间。

段式管理

段页式管理

段页

虚拟内存

​ 让用户感觉像是在分段,但实际上是分页管理

页框是什么

高级调度:

​ 功能:调度对象是作业。其主要功能是根据某种算法,其选择从就绪队列中选择哪个进程进入内存执行,以便后续的执行。决定从外存中处于后备队列中的哪几个作业调入内存,为创建进程、分配必要的资源。

​ 关系:高级调度与中级调度之间的关系是,高级调度将作业从后备队列中选择并将它们加载到内存中,然后中级调度负责将这些作业分配给可运行队列。高级调度与低级调度之间的关系是,它确定了哪些进程将被带入内存,以供后续的执行。

中级调度:

又称为内存调度。引入中级调度的主要目的是,提高内存利用率和系统吞吐量。

​ 功能:中级调度的主要任务是管理内存中的进程。它可以将某些进程从内存中暂时移出,以便为其他进程腾出空间,以减轻内存压力,提高内存利用率和系统吞吐量。

​ 关系:中级调度与高级调度之间的关系是,它接受高级调度分配的作业,将它们加载到内存中,并可以在必要时将它们暂时移出内存。中级调度还与低级调度之间有关,因为它可以调整进程的内存分布,以优化系统性能。

低级调度:

​ 功能:低级调度是最频繁的调度级别,其任务是从就绪队列中选择下一个要执行的进程。它控制着CPU的分配,决定哪个进程将在CPU上执行,以确保公平性和性能。

​ 关系:低级调度与高级调度之间的关系是,它执行高级调度选择的进程,将其分配给CPU执行。它还与中级调度之间有关,因为中级调度可能会将某些进程暂时移出内存,而低级调度负责在需要时将它们带回内存。

你可能感兴趣的:(计算机系统基础,网络,服务器,linux)