存储器管理
存储器层次结构
存储层次至少具有三级:最高层为CPU寄存器,中间为主存,最底层是辅存。
程序的装入和链接
程序装入方式:
- 绝对装入方式:绝对装入程序按照装入模块的地址,将程序和数据装入内存。
- 可重定位方式:在采用可重定位装入程序将装入模块装入内存后,会使装入模块中的所有逻辑地址与实际装入内存的物理地址不同。
- 动态运行时装入方式:装入内存后的所有地址都仍然是相对地址,而将相对地址转换为绝对地址是在程序真正执行的时候。
程序链接方式:
内存管理
内存分配方式
单一连续分配:将内存分为系统区、用户区,将系统区的内存交给操作系统使用,而用户区内存分配给用户使用。
固定分区分配:内存空间被划分为若干个固定大小的区域,每个分区提供给某个进程使用。
动态分区分配:根据进程实际需要,结合数据结构动态分配内存。
- 位图:由位图标记相关分区是否被使用
- 空闲链表:由双向链表将空闲区域作为节点相连
相关分配算法
- 首次适应算法:从头部顺序查找,分配内存使用。
- 最佳适应算法:空闲区链表按照容量大小排序,遍历空闲区链表找到最佳空闲区,分配内存使用。
- 快速适应算法:拥有多个空闲区链表,每个空闲区链表存储一种容量的空闲区,快速找到合适的内存分配使用。
内存回收过程
- 回收区和一块空闲区相邻,且回收区在空闲区下边:将回收区包含进空闲区
- 回收区和一块空闲区相邻,且空闲区在回收区下边:将回收区和空闲区合并,新的空闲区采用回收区的地址
- 回收区在两块空闲区中间:将三个区域合并,新的空闲区使用顶部的空闲区地址
- 单独的回收区:转为空闲区插入空闲区链表
内存存储管理
页式存储管理:将进程逻辑空间等分为若干个页面,物理内存空间分为若干个物理块,以页面为单位将进程装入物理块。由页表记录进程逻辑空间与物理空间的映射
- 缺点:由于页面大小的原因,会导致碎片多,单一的页式存储也会导致页表占用内存空间大。
- 优点:符合计算机的存储管理要求
- 解决方案:采用多级页表,防止一次页表的页表项过大
段式存储管理:将进程逻辑空间划分为若干段(非等分),由段表记录逻辑空间到物理空间的映射。
- 优点:适合用户需求,满足程序的共享
段页式存储管理:结合了提高内存利用率的分页管理、满足用户需求的分段,将进程先分为段,再分为页。
页面置换算法
当发生缺页异常的时候,需要相关的页面置换算法。
最优页面置换算法:将不再需要或者很久以后才需要的页面置换出去,这是一种理想的置换算法。
先进先出页面置换算法:由操作系统维护一个所有在当前内存中的页面的链表,缺页时移除头部的页,并且把新的页添加到表尾。
最近最少使用页面置换算法:在缺页中断时,置换未使用时间最长的页面。
虚拟地址空间
将物理内存地址暴露给进程的缺点:
- 用户程序可以寻址内存中的字节,容易破坏操作系统
- 多个用户程序容易发生冲突,并发困难
虚拟地址空间:创建了一种抽象内存供程序使用。地址空间是进程可以用来寻址内存的地址集。每个进程都有它自己的地址空间,独立于其他进程的地址空间。
在没有虚拟内存的计算机上,系统直接将虚拟地址送到内存中线上,读写操作都使用同样地址的物理内存。在使用虚拟地址空间技术时,虚拟地址不会直接发送到内存总线上。相反,会使用 MMU内存管理单元
把虚拟地址映射为物理内存地址。
基址寄存器和变址寄存器:采用了虚拟地址空间后,要实际定位到程序的物理内存地址,采用动态重定位方法,使用CPU中的基址寄存器、变址寄存器来对地址空间转换为物理内存地址。
- 基址寄存器:存储数据内存的起始位置
- 变址寄存器:存储应用程序的长度。
虚拟地址空间由固定大小的单元组成,这种固定大小的单元称为 页(pages)
。而相对的,物理内存中也有固定大小的物理单元,称为 页框(page frames)
。
映射关系由页表进行管理,如果MMU 注意到该页面没有被映射,于是 CPU 会陷入(trap)
到操作系统中。这个陷入称为 缺页中断(page fault)
或者是 缺页错误
。操作系统会选择一个很少使用的页并把它的内容写入磁盘。
针对虚拟地址到物理地址映射速度优化主要有:TLB(转换检测缓冲区)位于MMU里面。
TLB
TLB是一个内存管理单元用于改进虚拟地址到物理地址转换速度的缓存。
TLB是位于内存中的页表的cache,如果没有TLB,则每次取数据都需要两次访问内存,即查页表获得物理地址和取数据.
虚拟内存
交换技术:针对于内存不足以程序运行的情况,有两种方式,第一种是交换,将进程放入内存中执行后,再把它放回磁盘。故空闲进程会存放在磁盘中。第二种是虚拟内存。
虚拟存储器,是指具有请求调入功能和置换功能,能从逻辑上对内存容量加以扩充的一种存储器系统。
具有多次性、对换性和虚拟性三大主要特征。
- 多次性:多次性是指一个作业被分成多次调入内存运行
- 对换性:对换性是指允许在作业的运行过程中进行换进、换出
- 虚拟性:虚拟性是指能够从逻辑上扩充内存容量
虚拟内存主要由虚拟存储器实现,具体内存管理也大体一样,分为:请求分页、请求分段、请求段页式,
相关置换算法:
- 先进先出算法(FIFO)
- 最不经常使用算法(LFU)
- 最近最少使用算法(LRU)
文件系统
文件系统存储在磁盘
中。大部分的磁盘能够划分出一到多个分区,叫做磁盘分区
。每个分区都有独立的文件系统,每块分区的文件系统可以不同。磁盘的 0 号分区称为 主引导记录(MBR)
,用来引导(boot)
计算机。在 MBR 的结尾是分区表(partition table)
。
当计算机开始引 boot 时,BIOS 读入并执行 MBR。
引导块
MBR 做的第一件事就是确定活动分区
, 读入引导块(boot block)
并执行。引导块中的程序将加载分区中的操作系统。为了一致性,每个分区都会从引导块开始,即使引导块不包含操作系统。引导块占据文件系统的前 4096 个字节,从磁盘上的字节偏移量 0 开始。引导块可用于启动操作系统。
超级块
超级块 的大小为 4096 字节,从磁盘上的字节偏移 4096 开始。超级块包含文件系统的所有关键参数
- 文件系统的大小
- 文件系统中的数据块数
- 指示文件系统状态的标志
- 分配组大小
在计算机启动或者文件系统首次使用时,超级块会被读入内存。
空闲空间块
用位图或者链表管理空闲块。
inode
索引节点。它是一个数组的结构,每个文件有一个 inode,inode 非常重要,它说明了文件的方方面面。
- 模式/权限(保护)
- 所有者 ID
- 组 ID
- 文件大小
- 文件的硬链接数
- 上次访问时间
- 最后修改时间
- inode 上次修改时间
文件分为两部分,索引节点和块。一旦创建后,每种类型的块数是固定的。
文件的实现
连续分配:按照连续数据块进行分配。
- 优点:实现简单、高性能
- 缺点:碎片问题
链表分配:按照链表方式分配数据块,节点的是磁盘指针
- 优点:充分利用数据块
- 缺点:不支持随机访问,IO代价大
inode:给每个文件赋予一个称为 inode(索引节点)
的数据结构,每个文件都与一个 inode
进行关联,inode 由整数进行标识。只有在文件打开时,其 inode 才会在内存中。
* 文件的字节数
* 文件拥有者的User ID
* 文件的Group ID
* 文件的读、写、执行权限
* 文件的时间戳,共有三个:ctime指inode上一次变动的时间,mtime指文件内容上一次变动的时间,atime指文件上一次打开的时间。
* 链接数,即有多少文件名指向这个inode
* 文件数据block的位置
目录的实现
目录项提供了查找文件磁盘块所需要的信息。目录系统的主要功能就是 将文件的 ASCII 码的名称映射到定位数据所需的信息上。
对于采用 inode 的系统,每个目录项,由两部分组成:所包含文件的文件名,以及该文件名对应的inode号码。
共享文件
硬链接:多个文件名指向同一个inode号码。【inode链接数会发生变化】
ln 源文件 目标文件
软链接:文件A和文件B的inode号码虽然不一样,但是文件A的内容是文件B的路径。
ln -s 源文文件或目录 目标文件或目录
磁盘调度算法:
- 先来先服务:磁盘臂按照FIFO原则移动
- 最短路径优先:磁盘臂按照最短路径优先原则移动
- 电梯算法:磁盘臂向一端移动后回来
提升性能
- 高速缓存:块高速缓存、缓冲区高速缓存
- 块提前读:提前预读下一个块【针对顺序读取的文件】
- 减少磁盘臂运动:把有可能顺序访问的块放在一起,当然最好是在同一个柱面上,从而减少磁盘臂的移动次数
IO
I/O 分为两种:物理I/O 和 逻辑I/O(Logical I/O)
。
物理 I/O 通常是从磁盘等存储设备实际获取数据。逻辑 I/O 是对存储器(块,缓冲区)获取数据。
大部分物理IO(physical I/O)
是异步的。CPU 传输完成后会转而做其他事情,等到中断发生后,CPU 才会回到传输这件事情上来。
比较条件 | 同步传输 | 异步传输 |
---|---|---|
概念 | 块头序列开始 | 它分别在字符前面和后面使用开始位和停止位。 |
传输方式 | 以块或帧的形式发送数据 | 发送字节或者字符 |
同步方式 | 同步时钟 | 无 |
传输速率 | 同步传输比较快 | 异步传输比较慢 |
时间间隔 | 同步传输通常是恒定时间 | 异步传输时间随机 |
开销 | 同步开销比较昂贵 | 异步传输开销比较小 |
是否存在间隙 | 不存在 | 存在 |
实现 | 硬件和软件 | 只有硬件 |
示例 | 聊天室,视频会议,电话对话等。 | 信件,电子邮件,论坛 |
缓冲
通常情况下,从一个设备发出的数据不会直接到达最后的设备。其间会经过一系列的校验、检查、缓冲等操作才能到达。优点:先到达缓冲区,从而消除缓冲区填满速率和缓冲区过载。
共享和独占
有些 I/O 设备能够被许多用户共同使用,但是某些设备必须具有独占性,即只允许单个用户使用完成后才能让其他用户使用。
此时采用**SPOOLing技术(假脱机技术)**将物理设备虚拟为多个逻辑设备,在队列中调用设备,从而实现共享。
一共有三种控制 I/O 设备的方法
- 使用程序控制 I/O
- 使用中断驱动 I/O
- 使用 DMA 驱动 I/O
使用程序控制 I/O
使用程序控制 I/O 又被称为 可编程I/O
,它是指由 CPU 在驱动程序软件控制下启动的数据传输,来访问设备上的寄存器或者其他存储器。CPU 会发出命令,然后等待 I/O 操作的完成。由于 CPU 的速度比 I/O 模块的速度快很多,因此可编程 I/O 的问题在于,CPU 必须等待很长时间才能等到处理结果。CPU 在等待时会采用轮询(polling)
或者 忙等(busy waiting)
的方式,结果,整个系统的性能被严重拉低。
- CPU 请求 I/O 操作
- I/O 模块执行响应
- I/O 模块设置状态位
- CPU 会定期检查状态位
- I/O 不会直接通知 CPU 操作完成
- I/O 也不会中断 CPU
- CPU 可能会等待或在随后的过程中返回
使用中断驱动 I/O
在 CPU 等待 I/O 设备的同时,能够做其他事情,等到 I/O 设备完成后,它就会产生一个中断,这个中断会停止当前进程并保存当前的状态。
- CPU 进行读取操作
- I/O 设备从外围设备获取数据,同时 CPU 执行其他操作
- I/O 设备中断通知 CPU
- CPU 请求数据
- I/O 模块传输数据
使用DMA的 I/O
DMA即直接内存访问,它意味着 CPU 授予 I/O 模块权限在不涉及 CPU 的情况下读取或写入内存。即 IO 过程不需要 CPU 的参与。由于 DMA 设备可以直接在内存之间传输数据,而不是使用 CPU 作为中介,因此可以缓解总线上的拥塞。DMA 通过允许 CPU 执行任务,同时 DMA 系统通过系统和内存总线传输数据来提高系统并发性。
中断处理程序
中断处理程序步骤:
- 保存所有没有被中断硬件保存的寄存器
- 为中断服务程序设置上下文环境,可能包括设置
TLB
、MMU
和页表 - 为中断服务程序设置栈
- 对中断控制器作出响应,如果不存在集中的中断控制器,则继续响应中断
- 把寄存器从保存它的地方拷贝到进程表中
- 运行中断服务程序,它会从发出中断的设备控制器的寄存器中提取信息
- 操作系统会选择一个合适的进程来运行。如果中断造成了一些优先级更高的进程变为就绪态,则选择运行这些优先级高的进程
- 为进程设置 MMU 上下文,可能也会需要 TLB,根据实际情况决定
- 加载进程的寄存器,包括 PSW 寄存器
- 开始运行新的进程
设备驱动程序
操作系统通常会将驱动程序归为 字符设备
和 块设备
提供 I/O 设备到设备控制器转换的过程的代码称为 设备驱动程序(Device driver)
设备驱动程序接受到读写请求后,会检查当前设备是否在使用,如果设备在使用,请求被排入队列中,等待后续的处理。如果此时设备是空闲的,驱动程序会检查硬件以了解请求是否能够被处理。在传输开始前,会启动设备。等待设备就绪完成,再进行实际的控制。控制设备就是对设备发出指令。
设备控制器的主要主责是控制一个或多个 I/O 设备,以实现 I/O 设备和计算机之间的数据交换。
设备控制器接收从 CPU 发送过来的指令,继而达到控制硬件的目的。
了解更多知识干货,♂️关注公众号:学编程的文若