1.内存
1.1内存概述
内存是用于存放数据的硬件,程序执行前都需要先放到内存中才能被CPU处理。
内存中有许多存储单元,每个存储单元都有对应地址。
- 如果计算机按 字节编址 ,每个存储单元的大小为1字节,1B,8个二进制位
- 如果字长为16的计算机按 字长编址 ,每个存储单元大小为1个字,每个字的大小为16个二进制位
ASCii字符集:只有英文、数字、英文符号,占1个字节。
GBK字符集:汉字占2个字节,英文、数字占1个字节。
UTF-8字符集:汉字占3个字节,英文、数字占1个字节。
相对地址(逻辑地址)
绝对地址(物理地址)
从写程序到程序运行:编辑源码文件—编译—链接—装入
1.2地址转换
三种方式完成逻辑地址到物理地址的转换:
- 绝对装入
- 只适合于单道程序环境
- 编译时就知道要将程序放入内存的哪个位置,产生绝对地址
- 静态重定位
- 由装入模块完成,又称可重定位装入
- 一个作业装入内存时,必须分配其要求的全部内存空间,如果没有足够的内存,就不能装入该作业
- 作业一旦进入内存中,在运行期间不可移动,也不能再次申请内存空间
- 装入时将逻辑地址转换为绝对地址
- 动态重定位
- 又称动态运行时装入,程序把装入模块装入内存后,并不会立即把逻辑地址转换为物理地址,而是把地址转换推迟到程序真正要执行的时候才进行
- 需要重定位寄存器存放装入模块存放的起始位置
- 可分配到不连续的存储区,运行时根据需要动态申请分配内存,可以向用户提供一个比存储空间大得多的地址空间
- 允许程序在内存中发生移动
- 运行时逻辑地址变为绝对地址,可设置重定位寄存器的值动态修改地址
三种链接方式:
- 静态链接:在程序运行前先将各目标模块及他们所需要的库函数连接成一个完整的模块
- 装入时动态链接:边将模块装入内存时,装边链接
- 运行时动态链接:执行时需要模块,才链接,便于对模块的修改和更新,用不到的模块就不需要装入内存
2.内存管理
-
操作系统负责内存空间的分配与回收
-
操作系统需要提供某种技术从逻辑上对内存空间进行扩展,操作系统的虚拟性
-
操作系统需要提供地址转换功能,负责程序的逻辑地址与物理地址的转换,程序员只考虑逻辑地址即可
-
操作系统需要提供内存保护功能,保证各进程在各自的存储空间内运行,互不干扰
-
设置上下限寄存器
-
用界地址寄存器、重定位寄存器进行越界检查
-
2.1内存空间的扩展
2.1.1覆盖技术
固定区,覆盖区
不可被同时访问的程序段放到同一个覆盖区,存储地址选其中最大的
缺点:必须有程序员声明覆盖结构,操作系统才能自动覆盖,对用户不透明
2.1.2交换技术
- 设计思想:内存空间紧张时,系统将内存中的某些进程暂时换入外存(磁盘),把外存就绪状态的进程换入内存(内存与磁盘之间的调度)
- 中级调度:就是决定哪个处于挂起状态的进程重新调入内存
- 将磁盘分为文件区和对换区两部分。
- 文件区:追求存储空间的利用率,采用离散分配方式
- 对换区:占磁盘很小一部分,被换出的进程就存放到对换区,对换区追求换入换出速度,采用连续分配方式
- PCB会常驻内存
2.1.3虚拟缓存技术
时间局限性:如果执行了程序中的某条指令,不久之后这条指令很可能再次执行
空间局限性:一旦程序访问了某个存储单元,在不久之后,附近的存储单元也很可能被访问
高速缓冲技术:将近期访问的数据放到更高速的存储器中,暂时用不到的数据放到更低速存储器中。
虚拟内存:在操作系统的管理下,在用户看来似乎有一个比实际内存大得多的内存。
2.2内存空间的分配
-
内部碎片:分配给某个进程的内存区域中,有些没用上
-
外部碎片:内存中某些空闲分区由于太小难以利用
-
紧凑技术:解决外部碎片问题,内存分区过于零碎导致放不进大的进程就会有外部碎片,紧凑技术把未使用小分区合到一起,紧凑技术伴随着起始地址的修改
连续分配管理方式:指为用户进程分配的必须是一个连续的内存空间。
离散分配管理方式:为用户分配的可以是一些离散的内存空间
连续分配:
-
单一连续分配
- 在单一连续分配方式中,内存分为系统区(低地址)和用户区
- 内存中只能由一道用户程序,独占整个用户区
- 优点:无外部碎片,可采用覆盖技术扩充内存,内存可以不采取保护措施
- 缺点:有内部碎片,有很大一部分用户区空闲,存储器利用率低
-
固定分区分配
- 多进程运行:
分区大小相等:缺乏灵活性,适合于一台计算机控制多个相同对象
分区大小不等:可以满足不同大小的进程的需要 - 操作系统需要建立一个数据结构–分区说明表,通常按照分区大小排列,每个表包含对应分区的大小、起始地址、状态(是否被分配)
- 缺点:有内部碎片,存储器利用率低;用户进程过大就需要覆盖技术
- 多进程运行:
-
动态分区分配
- 可变分区分配,不会预先划分分区而是进程装入内存时根据进程大小动态建立分区
- 两个空闲分区相邻可以合并为一个
- 如何记录内存使用情况?两种数据结构:空闲分区表、空闲分区链
- 当有好几个空闲分区满足要求时,装入哪个分区?按照动态分区分配算法
动态分区分配算法:
-
首次适应算法:从低地址开始查找,根据空闲分区表(空闲分区链)找到第一个能满足大小的空闲分区
-
最佳适应算法:空闲分区按照容量递增次序链接,先使用小分区,为大进程到来时能有连续的大片空间
- 每次用完一个空闲分区就要更新空闲分区表/链,再次根据分区容量排序
- 每次都选最小的分区进行分配,会留下越来越多的更小的空闲分区,难以利用的内存块,因此这种方法会产生很多外部碎片
-
最大适应法:按容量递减次序链接,先使用容量大的空闲分区
-
邻近适应算法:也是按照地址递增顺序排列。首次适应算法每次都要从低地址链头进行寻找,每次都要经过低地址那些分区,增加了开销。邻近使用算法可以从上一次查找结束的位置开始检索
3.离散分配
3.1分页存储管理
-
分页存储管理:将内存空间分为一个个大小相等的分区,每个分区就是一个页框(页帧、内存块、物理块),每个页框都有页框号,从0开始。
-
将用户进程的地址空间分为与页框大小相等的一个个区域,称为页面/页(页号从0开始)。
-
页框不能太大,最后一个进程可能会没有页框大,会产生内部碎片。页面与页框一一对应,各页面不必连续存放,也不必按照先后顺序。
求物理地址:
页号=逻辑地址/页面长度(取整数)
页内偏移量=逻辑地址%页面长度
计算机中常用二进制表示逻辑地址:
3.1.1页表
-
页表可以知道每个页面在内存中的存放位置
-
页表有页号和块号两部分,页号指页面,块号指页框
-
一个进程对应一张页表,进程的每一页对应一个页表项
-
物理地址=M号起始地址(页块号x内存大小)+偏移量
基本地址变换机构-用于实现逻辑地址到物理地址转换的一组硬件机构:
3.1.2快表(快表相当于页表项的副本)
-
快表又称联想寄存器(TLB),是一种访问速度比内存快很多的高速缓冲存储器,用来存放当前访问的若干页表项,以加速地址变换过程。
-
内存中的页表被称为慢表,快表相当于慢表的副本
-
快表中的数据一定是在内存中的
3.1.3两级页表(页表需要时才入内存)
单级页表存在的问题:
- 很多时候进程在一段时间内只需要访问某几个页面就可以正常运行了,因此没必要让整个页表都常驻内存
- 解决:可以在需要访问页面时才把页面调入内存(虚拟存储技术),可以在页表中增加一个标志位,用于表示该页表是否调入内存
- 若想访问的页面不在内存中,就会产生缺页中断(内中断)
- 页表必须连续存放,需要占用多个连续页框
为了能离散的放入页表,为页表再建立一个页表,叫页目录表/外层页表/顶层页表。
例1:已知:32位逻辑空间,页面大小位4KB,页表项大小为4B。
例2:
3.2分段存储管理
分段:地址空间按照自身的逻辑关系,划分为若干个段,每段都有一个段名,每段从0开始编址。
每个段在内存中占据连续空间,但是各段之间可以不相邻,CPU以段号来区分段。
3.2.1段表
物理内存是4GB,所以物理地址需要用32位来表示,也就是每个段表项中的基址字段需要32位。加上段长限制的16位,总共有16+32=48位,即6字节。
3.2.2分页和分段对比
3.3段页式管理
- 先按逻辑分段,再对各段进行分页,地址结构是二维的。
- 段表:段号、页表长度,页表存放块号(起始地址);段表项长度相等,段号隐藏。
- 页表:页号、内存块号;页表项长度相等,页号隐藏。
- 一个进程对应一个段表,但可能对应多个页表。
- 段表寄存器。
3.4请求分页管理
请求调页:所访问的信息不存在,由操作系统负责将所需信息从外存调入内存
页面置换:内存空间不够,由操作系统负责将内存中的暂时不用的信息换到外存
请求页表:
缺页中断:属于内中断
- 当访问页面不存在的时候,就会产生一个缺页中断,由操作系统的缺页中断程序处理中断。此时缺页进程阻塞,调页完成后再次唤醒,放回就绪队列。
- 如果内存有空闲块,则分配一个空闲块;没有就需要置换出一个页面。
- 可能多次缺页中断
页面置换算法
页面换入换出涉及到磁盘I/O开销大,置换算法追求更小的缺页率。
-
最佳置换算法OPT:
- 每次选择的淘汰页面将是最长时间不再被访问的页面
- 缺页未必置换,只有在内存不够才会置换
- 缺页率=缺页中断发生次数/总访问次数
- 由于最佳置换算法要提前知道接下来的访问顺序,因此他是理想的
-
先进先出置换算法FIFO:
- 淘汰的页面是最早进入的页面
- 当系统的可用内存块增加,缺页次数反而增多,这就是Belady异常(贝莱迪异常)
-
最近最久未使用置换算法LRU
- 淘汰的页面是最近最久未使用页面
- 需要专门硬件支持,开销大
- 淘汰的页面是最近最久未使用页面
-
时钟置换算法(CLOCK)
-
3.5页面分配策略
- 驻留集:请求分页管理中给进程分配的物理块集合。
- 驻留集一般要小于进程总大小,否则并发度下降
- 但是不能太小,否则频繁缺页
- 固定分配:物理块数量不变
- 可变分配:物理块数量可变
- 局部置换:发生缺页时只能选进程自己的物理块进行置换
- 全局置换:可用操作系统空闲物理块,也可以别的进程持有的物理块置换到外存
三种分配策略:固定分配局部置换、可变分配全局置换(缺页就分配新的物理块)、可变分配局部置换(根据缺页频率来增加或减少物理块)。
何时调入页面?
- 预调页策略:运行前,根据空间局部性,一次调入若干个相邻页面,主要用于进程首次调入,程序员指出应先调入哪些部分
- 请求调页策略:运行时,缺页时调入,但每次只能调入一页,I/O开销比较大
从何处调入页面:
-
外存有足够多的对换区
-
缺少足够的对换区
抖动(颠簸)现象:频繁的页面调度(主要原因是分配给进程的物理块数不够)。
工作集:指在某段时间间隔里,进程实际访问页面的集合