内存管理
内存管理相关概念
内部碎片、外部碎片(紧凑技术解决)
局部性原理:
- 时间局部性:如果执行了某条指令,不久之后指令和数据都很可能再次执行或访问。(循环
- 程序访问了某个存储单元,其附近的存储单元也可能被访问。
操作系统对于内存管理需要实现的功能
- 操作系统负责内存空间的分配和回收
- 操作系统需要提供某种技术从逻辑上对内存空间进行扩充(虚拟内存)
- 需要提供地址转换功能(逻辑地址->物理地址)
- 提供内存保护功能,进程运行互不干扰(上下位寄存器、从定位寄存器和限长寄存器进行越界检查)
- 操作系统负责内存空间的分配和回收
- 操作系统如何记录内存当前状态?
固定分区分配:通过分区说明表,记录内存的分配与回收(分区号、大小、起始地址、状态)
动态分区分配:空闲分区表 or 空闲分区链- 操作系统如何为新的进程分配内存?
动态分区分配算法
可能出现的情况:空闲分区表记录数量不变,表项需要修改(分配分区大);空闲分区表记录数量减少一个(分配大小相等)- 操作系统如何将结束的进程使用的内存进行回收?
可能出现的情况:(1)回收后产生的空闲分区和上或下分区相邻,需要两个分区合并(数量:表项不变)(2)回收的分区上下都是空闲分区,需要三个相邻分区合并(数量:表项-1)(3)回收分区上下都无空闲分区,产生新的空闲分区(数量:表项+1)
-
连续分配管理方式(分配的空间一定连续,会产生碎片的缺点)
- 单一连续分配,内存中只能有一道用户程序,分为系统区和用户区。(好处:简单、无外部碎片、不一定提供内存保护;缺点:单用户单任务,内部碎片,空间利用率低)
- 固定分区分配:将用户空间分为若干固定大小分区,每个分区可以装入一道作业,可运行多道程序管理方式。(又分为分区大小相等与不等两种方式)相等分区不够灵活、但实现简单适用于控制多个相同对象的情况。分区大小不等灵活性强,满足不同需求。
实现简单,无外部碎片,数据不共享。
缺点:用户程序太大,可能不能满足需求;内部碎片,利用率低。 - 动态分配分区:不预先划分内存分区,在进程状图内存时根据进程大小动态建立分区,使其满足进程需要。无内部碎片,但有外部碎片。
-
非连续分配管理方式
- 分页存储管理
内存空间划分为大小相等的分区,每一个分区是一个页框,从0开始编号。将用户进程也分割成相同大小的区域,成为页(页面),也有编号页号。
页框不能设置的太大,否则会产生较大的碎片。页和页框一一对应。- 逻辑地址和物理地址的转换:物理地址 = 页的起始地址+相对于该页的偏移量。(1)逻辑地址对应的页号(2)页号对应的页面的起始地址(3)逻辑地址在页面的偏移量
- 页面大小一般为2的整数幂,若为2^kB逻辑地址的2进制表示 = 页号+页内偏移量(长度为k)
- 页表:一个进程对一个页表,记录进程页面和实际存放内存块之间的对应关系。页表项由页号和块号组成
- 基本地址变换机构:页表寄存器(页表起始地址+页表长度)页表长度、页表项长度、页面大小
- 具有快表的地址变换机构
快表: 存放在相较于内存访问更高速的存储器中,存放当前访问的若干页表项,加速地址变换(与页表对应)。
快表命中的时候,一次访存(内容);快表不命中,两次访存(页表和内容)
- 两级页表
解决单级页表连续占用多个内存块的问题(页号,页内偏移量)
利用页目录表,进行页表分组。每个分组大小刚好能装入一个内存块,不同分组离散保存在不同内存块中。(一级页号,二级页号,页内偏移量)
页目录表保存一级页号以及其对应的分组的页表存储的内存块号;二级页表保存,二级页号以及对应的内存单元存储在的内存的块号。
二级页表:三次访存(页目录表,二级页表,目标单元)
多级页表机制:各级页表的大小不能超过一个页面
- 基本分段存储管理
进程按照程序自身逻辑关系划分为若干个端,每段从0开始编址。内存分配规则:以段为单位进行分配,每个端占据连续的内存空间,各段之间是离散的。- 逻辑地址(段号、段内地址)
段号决定每个进程分段的最大数;段内地址决定段的最大长度 - 段表(段号、段长、段基址):每个分段的长度可能不一样。页长都一样。(段号可以隐藏,因为段表项长度固定)
- 段表寄存器(段表始址,段表长度)
- 逻辑地址(段号、段内地址)
地址变换过程:
分段、分页管理对比
- 页是物理信息单位,长度固定,目的是实现离散分配,提高内存利用率,方便系统管理,用户不可见。
- 段是逻辑信息单位,长度不固定,目的是更好满足用户需求,对用户可见,编程时需要显示给出段名。
- 分页用户进程地址一维 —> 对用户而言进程的存储是连续的。
- 分段用户进程地址二维—>用户知道进程离散存储。
- 分段更容易实现信息共享和保护(按照逻辑进行进程划分)。
- 段页式管理方式
分段、分页优点、缺点比较
将进程按照逻辑模块分段,然后将各个段进行分页,内存空间大小分为大小相同的内存块
- 逻辑地址结构(段号、页号、页内偏移量):用户知道进程分段,但不知道分段后分页,所以对用户而言地址结构是二维的。
- 段表(一个进程一个):(段号、页表长度、页表存放块号<查页表位置>),段表项长度相等。
- 页表(一个段一个):(页号,内存块号<查内存位置>)
- 段表寄存器(段表起始,段表长度)
地址转换:有三次缓存(段表、页表、数据空间)
- 动态分区分配算法(连续分配方式)
- 首次适应算法:按照地址顺序排列,从低地址顺序检索,找到第一个满足要求的分区进行分配。
- 最佳适应算法:按照容量递增的顺序进行连接,顺序查找,找到第一个满足要求、大小最小的分区。(缺点:留下越来越多很小的外部碎片)
- 最坏适应算法:每次分配优先使用最大的空闲分区。按容量递减的分区进行分配(后来的大进程可能无法运行)
- 邻近适应算法:按地址排列,每次从上次结束的位置开始查找。(循环链表)
1,4链表不会重新排列;2,3链表顺序会动态变化
- 操作系统需要提供某种技术从逻辑上对内存空间进行扩充(虚拟内存)
虚拟存储技术
第一部分都是传统管理方式,其特征有:一次性(作业必须一次性装入内存后才能运行);驻留性(作业装入内存会一直驻留内存,直到运行结束)
基于局部性原理,程序装入时,将很快要用到的部分装入内存,暂时用不到的驻留在外存,装入部分程序就可以让进程开始运行。
程序执行时,所访问的信息不在内存时,操作系统负责将需要的信息从外存调入内存。
当内存已满而需要从外存调入信息时,操作系统将内存中暂时不用的信息换到外存。
最终的结果是,用户看来似乎有一个比实际内存大的多的内存,这就是虚拟内存。是逻辑扩充
虚拟内存特征
- 多次性:作业无需一次性装入才可运行
- 对换性:作业无需一直驻留内存,信息可以外存内存换入换出。
- 虚拟性:用户看来,逻辑上扩充
虚拟内存实现技术
请求调页功能,页面置换功能
- 请求分页管理方式
- 页表机制
不仅需要记录逻辑地址和物理地址的关系,还需要记录状态(是否调入内存)、访问字段(访问情况的指标,用于选择置换哪些页面)、修改位(页面是否被修改过,决定是否写会外存)、外存地址
- 缺页中断机构(缺页中断:内中断)
当进程需要运行的部分不在内存中,会产生缺页中断,操作系统会处理该中断
缺页的进程会阻塞,调页完成后会将其唤醒
如果内存中有空闲块,则会为进程分配一个空闲块保存调入的新页面,修改页表项;如果没有,则采用页面置换算法选择一个页面淘汰,判断其需不需要写回外存,调入新页面,修改页表项。 - 地址变换机构
页面置换算法
缺页中断未必发生页面置换,没有空余内存块才发生页面置换。
- 页表机制
- 最佳置换算法(OPT)
每次选择的淘汰的页面以后永不使用,或者最长时间内不再被访问的页面
前提条件:知道访问序列是哪些,这个条件不现实,理想化的算法。
- 先进先出置换算法(FIFO)
每次选择淘汰最早进入内存的页面。
存在问题:belady异常,当分配的物理块增大的时候,缺页数不增反减。算法实现简单,但性能差。
- 最近最久未使用(LRU)
每次淘汰最近最久未使用的页面。访问字段记录该页面自上次被访问以来所经历的时间t,选择t最大的进行淘汰。
算法性能好(最接近OPT),实现困难,开销大
- 时钟置换算法(CLOCK)最近未用算法
- 简单CLOCK:页面设置访问位,当访问了页面,则访问位为1,其他为0,淘汰访问位为0的页面,简单的clock选择淘汰一个页面最多会经过两轮扫描。(数据结构,循环队列)
- 改进型CLOCK:优先淘汰没有被修改的页面,利用(访问位,修改位)二元组共同判断选择淘汰页面
算法规则:将所有可能被置换的页面排成一个循环队列
第一轮:从当前位置开始打描到第-一个(0,0) 的帧用于替换。本轮扫描
不修改任何标志位
第二轮:若第一轮扫描失败,则重新扫描,查找第一个(0,1) 的帧用于替换。本轮将所有扫描过的帧访问位设为0
第三轮:若第二轮扫描失败,则重新扫描,查找第一个(0,0) 的帧用于替换。本轮扫描不修改任何标志位
第四轮:若第三轮扫描失败,则重新扫描,查找第一个(0,1) 的帧用于替换。
由于第二轮已将所有帧的访问位设为0,因此经过第三轮、第四轮扫描一定会有一个帧被选中,因此改进型CLOCK 置换算法选择一-个淘汰页面最多会进行四轮扫描
性能、开销适中
-
需要提供地址转换功能(逻辑地址->物理地址)
不用的内存管理方式下,地址转换机制不同,可以对比学习。 -
提供内存保护功能,进程运行互不干扰(上下位寄存器、从定位寄存器和限长寄存器进行越界检查)
页面分配策略
- 驻留集:请求分页存储管理中给进程分配的物理块的集合。驻留集大小一般小于总进程的大小,但也不能太大。
- 进程运行期间,驻留集大小是否能改变:也分固定分配和可变分配
- 局部置换,全局置换:根据置换的页面是否只能是自己的
- 固定分配、局部置换:系统分配一定量物理块,运行期间不改变,置换时置换自己本身的页面。缺点:初始分配不好确定,灵活性低
- 可变分配,全局置换:刚开始分配一定物理块,运行时可改变,置换时选择一个未锁定的页面进行换出。进程发生缺页,就会获得一个新的物理块。
- 可变分配,局部置换:刚开始分配一定物理块,运行时可改变,置换时置换自己本身的页面。操作系统发现进程频繁缺页,会为其分配物理块,也会减少。
何时调入页面?
- 预调入策略:一次调入若干个相邻的页面,预测可能访问的页面,将其预先调入内存。主要应用于首次调入。
- 请求调页策略:运行期间发现缺页才开始调入
何处调入页面?
- 对换区:连续分配方式,更快;文件区,离散分配方式
- 对换区足够大,主要是内存和对换区交换数据。
- 对换区不足时,不会修改的数据从文件区调入内存,修改数据是内存和对换区的交换。
其他
- 按字节编址,每个存储单元的大小为一个字节。内存单元的大小看计算机编址方式。