操作系统之内存管理

汇总:Android小白成长之路_知识体系汇总【持续更新中…】

存储管理器

操作系统中管理分层存储体系的部分称为存储管理器,它的任务是有效地管理内存,记录哪些内存正在使用,哪些内存是空闲的,在进程需要时为其分配内存,在进程使用完后释放内存。

接下来介绍一些由简单到复杂的存储管理方案,由于最底层的高速缓存的管理由硬件来完成,我们只需要关注由软件部分完成的内存模型抽象即可。

无存储器抽象

最简单的存储器抽象就是根本没用抽象,每个程序直接访问物理内存:从0到某个上限的地址集合,每个地址对应一个可容纳一定数目二进制位的存储单位,通常是8个。使用这种方案的有三种变体:

在这里插入图片描述

第一种方案以前用在大型计算机和小型计算机中,现在很少使用了。第二种方案被用在一些掌上电脑和嵌入式系统中。第三种方案用于早期的个人计算机中,在ROM中的系统部分称为BIOS(Basic Input Output System,基本输入输出系统)。

地址空间

之前的无存储器方案把物理地址暴露给进程,会带来一些严重的问题,可能会造成系统崩溃无法运行,而且想运行多个程序会非常困难。因此,我们需要其他更好的方法

地址空间概念

要使多个应用程序同时处于内存中并且不互相影响,需要解决两个问题:保护和重定向。解决这些问题的办法是创造一个新的存储器抽象:地址空间。地址空间是一个进程可用于寻址内存的一套地址集合,每个进程都有自己独立于其他进程的地址空间(除去需要共享的情况)。比较难解决的是如何给每个进程分配一个自己独有的地址空间,例如如何使进程A的地址10对应的物理地址和进程B的地址10对应的物理地址不同,

有个比较简单的方法,那就是动态重定位,把每个进程的地址空间映射到物理内存不同的部分。需要使用基址寄存器和界限寄存器。当一个进程运行时,程序的起始物理地址被装载到基址寄存器中,程序的长度被装载在界限寄存器中,CPU硬件会在把地址发送到内存总线前,自动把基址值加到进程发出的地址值上,同时检查程序提供的地址是否大于或等于界限寄存器的值。如果访问的地址超过了界限,会产生错误并终止访问。在很多实际系统中,会对这两个寄存器进行保护,使得只有操作系统可以修改它们。

使用基址寄存器和界限寄存器重定位的缺点是:每次访问内存都要进行加法和比较运算,加法运算由于进位传递时间的问题,在没有使用特殊电路的情况下回显得很慢。

交换技术

通常情况下,所有进程所需的RAM数量总和要远远超出存储器能够支持的范围,最简单的策略是使用交换技术。

在这里插入图片描述

开始时内存中只有进程A,之后创建进程和C或者从磁盘中将它们换入内存,图d所示由于D要进入内存,所以先把A调出到磁盘,然后再把D放到A原来的位置上,之后A再要进来,就把B调出。此时A的位置和它一开始进来的位置是不一样的,所以需要在它换入的时候需要对其地址进行重定位,基址寄存器和界限寄存器就适用于这种情况。如果进程的数据段可以增长,需要在换入或者移动时给进程分配额外的内存,如果这些额外的内存使用完毕,就需要转移到更大的内存区域,或者对此进程进行终止。

空闲内存管理

在这里插入图片描述

  • 使用位图的存储管理:内存可能被划分成小到几十个字或大到几千字节的分配单元。每个分配单元对应于位图中的一位,0表示空闲,1表示占用。图a为五个进程和三个空闲区的内存划分,刻度表示内存分配单元,阴影区域表示空闲,图b为对应的位图。
  • 使用链表的存储管理:维护一个记录已分配内存段的链表,链表的一个结点要么包含一个进程,要么包含两个进程间的一块空闲区,如图c,P为进程,H为空闲区,第一个数值为起始地址,第二个值为长度,有几个算法可以为进程分配内存:
    • 首次适配:存储管理器沿着链表进行搜索,直到找到一个足够大的空闲区。空闲区的一部分供进程使用,剩下的一部分形成新的空闲区
    • 下次适配:工作方式和首次适配算法相同,但是它每次找到合适的空闲区都会记录当时的位置,以便下次寻找空闲区的时候可以从上次结束的地方开始搜索
    • 最佳适配:搜索整个链表,找出能容纳进程的最小空闲区
    • 最差适配:总是分配最大的可用空闲区,使新的空闲区比较大而可以继续使用
    • 快速适配:为那些常用大小的空闲区维护单独的链表,例如,有一个n项的表,该表的第一项是指向大小为4KB的空闲区链表表头的指针,第二项是指向大小为8KB的空闲区链表表头的指针,第三项指向大小为12KB的空闲区链表表头的指针,以此类推。

虚拟内存

虚拟内存基本思想:每个程序有自己的地址空间,这个空间被分割为多个块,每个块称作一页或页面。每一页有连续的地址范围。这些页被映射到物理内存,但不是所有页都必须在内存中才能运行程序,当程序引用到一部分在物理内存中的地址空间时,由硬件立刻执行必要的映射,当程序引用到一部分不在物理内存中的地址空间时,由操作系统负责将缺失的部分装入物理内存并重新执行失败的指令。

分页

在这里插入图片描述

由程序产生虚拟地址,它们构成虚拟地址空间,虚拟地址先被送到内存管理单元(Memory Management Unit, MMU),MMU再把虚拟地址映射为物理内存地址。虚拟地址空间按照固定大小划分成被称为页面的若干单元,在物理内存中对应的单元称为页框,页面和页框大小通常是一样的。由于虚拟地址空间比物理内存大,一般情况下虚拟页面有部分没有被映射到物理内存中,因此在实际的硬件中,用一个“在/不在"位记录页面在内存中的实际存在情况。

页表

在这里插入图片描述

虚拟地址被分成虚拟页号(高位部分)和偏移量(低位部分)两部分,虚拟页号用作表的索引,以找到该虚拟页面对应的页表项,由页表项找到页框号,然后再把页框号拼接到偏移量的高位部分,以替换虚拟页号,形成送往内存的物理地址。

在这里插入图片描述

页表项最重要的是页框号,其次是”在/不在“位,保护位指出一个页允许什么类型的访问,最简单的形式是这个域只有一位,0表示读/写,1表示只读,一个更先进的方法是使用三位,分别对应是否启用读、写、执行该页面。为了记录页面的使用情况,引入了修改位和访问位,在写入一页时由硬件自动设置修改位。如果一个页面被修改过,则必须把它写回磁盘,如果一个页面没有被修改过,则只需要简单地把它丢弃即可,因为它在磁盘上的副本任然是有效的。访问位的值被用来帮助操作系统在发生缺页中断时选择要被淘汰的页面,不再使用的页面要比正在使用的页面更适合淘汰。最后一位用于禁止该页面被高速缓存,假如操作系统正在紧张地循环等待某个i/O设备对它刚发出的命令作出响应,保证硬件是不断地从设备中读取数据而不是访问一个旧的高速缓存的副本是非常重要的,通过这一位来禁止高速缓存非常重要。

加速分页过程

在任何分页系统中,都需要考虑两个问题:

  • 虚拟地址到物理地址的映射必须非常快
  • 如果虚拟地址空间很大,页表也会很大

大多数程序总是对少量的页面进行多次的访问,因此只有很少的页表项会被反复读取。解决方案是可以为计算机设置一个小型的硬件设备,将虚拟地址直接映射到物理地址,而不必再访问页表,这种设备称为转换检测缓冲区(Translation Lookaside Buffer,TLB),又称快表。它通常在MMU中,包含少量的表项,每个表项记录了一个页面的相关信息,包括虚拟页号、页面的修改位、保护码和该页所对应的物理页框。除了虚拟页号,这些域与页表中的域是一一对应的。另外还有一位用来记录这个表项是否在使用。

将一个虚拟地址放入MMU中进行转换时,硬件首先通过将该虚拟页号与TLB中所有表项同时进行匹配,判断虚拟页面是否在其中,如果发现一个有效的匹配并且要进行的访问操作并不违反保护位,则将页框号直接从TLB中取出而不必再访问页表。如果MMU检测到没有有效的匹配项,就会进行正常的页表查询,然后从TLB中淘汰一个表项,用新找到的页表项代替它。许多现代的机器都是用软件实现TLB的,在这些机器中,TLB表项被操作系统显式地装载,当发生TLB访问失效时,不再是由MMU到页表中查找并取出需要的页表项,而是生成一个TLB失效并将问题交给操作系统解决,系统必须先找到该页面,然后从TLB中删除一项,接着装载一个新的项,然后再执行先前出错的指令。

针对大内存的页表

  • 多级页表:

在这里插入图片描述

如图,32位的虚拟地址被划分为10位的PT1域,10位的PT2域和12位的偏移量域,因为偏移量是12位,所以页面大小是4KB,共有2的20次方个页面。左边是顶级页表,有1024个表项,对应于10位的PT1域,当一个虚拟地址被送到MMU时,MMU首先提取PT1域并把该值作为访问顶级页表的索引,由索引顶级页表得到的表项中含有二级页表的地址或页框号。顶级页表的表项0指向程序正文的页表,表项1指向数据的页表,表项1023指向堆栈的页表,其他的表项(用阴影表示)未使用。把PT2域作为访问选定的二级页表的索引,以便找到该虚拟页面的对应页框号。二级页表可以扩充为三级、四级或更多及,级数越多,灵活性越大。

  • 倒排页表

实际内存中的每一个页框对应一个表项,而不是每个虚拟页面对应一个表项,但这样做会使得从虚拟地址到物理地址的转换变得很困难,可以使用TLB来解决,用TLB记录所有频繁使用的页面,地址转换就会很快。但是当TLB失效时,需要软件搜索整个倒排页表,可以建立一个散列表,用虚拟地址来散列,当前所有在内存中的具有相同散列值的虚拟页面被链接在一起。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Nbin_Newby

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值