内存管理技术

来源:互联网 发布:mac双系统怎么删除os 编辑:程序博客网 时间:2024/05/16 17:38

本文介绍界地址存储管理,页式存储管理,段式存储管理以及段页式存储管理。
是不带虚拟功能的哦~

我们知道,进程在运行前必须将整个程序装入内存,因而进程的逻辑空间不可以超过内存的物理空间大小。
存储管理的对比

本文的介绍基于此表格,故而看懂此表内容就不需要继续往下看了。

  • 单一连续区存储管理
      • 双对界
      • 交换与重定位
      • 覆盖技术
  • 页式存储管理
      • 多级页表
      • 反置页表
  • 段式存储管理
      • 段的共享保护
  • 段页式存储管理

单一连续区存储管理


进程空间和内存空间的对应关系是等长映射,即若进程长为l,在内存的起始地址为b,那么其对应的物理地址就是b~b+l-1。
内存分配表用于记录内存中所有已被分配的区域,若省略,则分配区域被分别记录在占有进程的PCB中。
空闲分配表则是记录内存中所有未被分配的区域。
首址寄存器保存正在运行的进程的起始地址,限长寄存器则是保存正在运行的进程的长度(可以理解为最大偏移量)。

这俩寄存器听名字就知道是啥功能,解释是不是有些多余了?
不过还是要说,系统会在进程将要投入运行时,将进程的首址和长度从内存分配表或PCB中取出送去寄存器。

在地址映射中,表中的a表示逻辑地址,b为进程的起始地址,如果a对应的物理地址不存在(即越界),映射表示为Ω,即没有意义。
映射的步骤为:程序确定逻辑地址->检测逻辑地址是否超过限长,超过则越界中断->首址寄存器+逻辑地址=物理地址。
单一连续存储地址映射

双对界

单对界(即单一连续存储区)限制一个进程在内存中仅占有一个连续区,双对界则允许一个进程占有两个连续区,一个用于保存代码(可共享),一个用于保存数据(进程独享)。
为了实现这个技术,我们需要硬件提供代码区的首址和限长寄存器(取指令使用),以及数据区的首址和限长寄存器(取数据使用)。

交换与重定位

交换是指进程在内存与外存之间的动态调度,我们又称换入(内存)换出(内存),用于缓解内存空间使用压力的,可以发现,交换的基本单位是整个进程,故而依旧不可以运行比内存空间大的程序。
也是由于交换的性质(进程换入/换出内存),导致其每次进出内存时所存放的位置可能发生变化,所以需要程序编址时不使用物理地址,即与内存存放位置不发生关联

所以进程逻辑地址就出现了。

重定位是基于程序编址与内存存放位置无关的条件,满足这种条件的程序称为可重定位程序(亦称浮动程序)。

由0开始编址的程序都满足重定位要求。
我记得从小学到高中,学生的班级是固定的,而且还有固定的座位,所以老师一看某个座位上的人不在,立刻就能知道是哪个学生不在,但大学就不一样了,学生上课的教室虽然固定,但是位置就不一定会固定了。

覆盖技术

这是一种将较大的程序装入较小的进程空间的一种技术。
这个技术的核心思想就是:只有全局代码和数据可以静态的放在内存(常驻内存),其他的部分则是分阶段的动态装入。

后装入内存的部分,覆盖之前对象所占用的空间。

虽然这种技术听着很简单,但是编写这样的程序是需要一定技巧的,但好处是,这不需要操作系统的特殊支持。

页式存储管理


这种方式允许一个进程占有内存空间的多个连续区(这些区域长度相同)。内存的这些连续区被称为物理页框,每个页框大小通常是2^i个单元(一般是B,牛逼一点儿可以是KB)。
每个页框内部由0开始编址,称为页内地址,物理页框整合后也由0开始编号,称页框号
假设内存容量为2^nB,每个页框长度为2^i:
页式内存空间划分

物理地址=物理页框首址 + 页内地址
    =页框号 x 2^i + 页内地址
实际上,将页框号作为高位,页内地址作为低位,即可得到物理地址。这是由于页框号放在高位时,是做了左移i位的运算,与x2^i作用相同。

进程空间被静态的划分为若干个等长的逻辑页面,对每个逻辑页面从0开始编址,称其为页内地址
我们假设有l个逻辑页面,每个逻辑页面长度为2^i:
页式进程空间的划分

逻辑地址=逻辑页首址 + 页内地址
    =逻辑页号 x 2^i + 业内地址
逻辑页号作高位,业内地址作低位即逻辑地址。

当进程运行时,需要将其各个逻辑页面存入物理页框中,其对应关系如下图所示:
逻辑页面与页框对应关系

我们可以看到,进程空间的逻辑页面是连续的,而其对应的物理页框却并不一定连续。

为了实现逻辑地址到物理之间的转换,我们采用页表记录逻辑页面与页框之间的对应关系,总页表来记录页框的使用情况,页表首址寄存器记录正在运行的进程的页表首址,页表长度寄存器记录正在运行进程的页表长度,快表(TLB)则是用于保存正在运行进程的页表的部分项目。
页表与快表

总页表就是位示图,空闲页面表,空闲页面链,快表这个玩意儿的地位和cache一样尊贵,所以快表查起来快,但是太贵了,造的大了成本就太高了,所幸当快表长度达到16时,查找页的命中率就已经足够高了。

地址映射步骤:
页式存储管理地址映射

映射描述是假定进程的虚拟地址空间是连续的,但是在很多情况下,进程的逻辑页面不连续会更方便些。
比如,并发……

多级页表

如果说某个进程需要的逻辑地址空间很大,但是页表连续区的长度难以满足,故而提出多级页表的概念,即将页表分为多级进行存放(比如说,两级页表包含内页表及外页表)。
但是多级页表会减缓地址映射的速度,一般说,级数越多,映射速度越慢。
二级页表

反置页表

传统页表是面向进程虚拟空间的,即对应进程的每个逻辑页面设置一个表项。
反置页表则不同,是面向内存物理页框的,即对应内存的每个物理构架设置一个表项。
反置页表

页式存储管理消除了外部碎片的问题,但是由于一个进程的长度通常并不恰好为页面长度的正数倍,故而在最后一页中会有部分空间未被用到,称此为页面零头

段式存储管理


分页对用户透明,分段对用户是可见的。
在段式存储管理中内存空间被动态的划分为若干长度不一的物理段,每个物理段在内存对应一个起始地址,称为段首址,在每一个物理段中由0开始编址,称为段内地址

和页式管理挺像的哈。

进程则是被静态的划分为长度不一的逻辑段,每个逻辑段对应一个程序单位(如主程序,子程序,数据区等),且具有一个符号名字,称为段名

进程的逻辑段对应内存的物理段,一个进程的多个逻辑段可存放于内存的多个不相连的物理段中,在物理上进程的段内地址是连续的,但段与段之间可以不连续。
为了实现这种映射关系,系统会使用段表记录段号与首址之间的关系,用空闲表记录并管理内存中的空闲区,使用段表首址寄存器保存正在运行的进程的段表首址,段表长度寄存器保存正在运行的进程的段表的长度,同样采用快表技术。

除了和页式管理存储中的名字有点区别,其他概念,越看越像。

地址映射的步骤:
段式地址映射

段式地址映射流程图

段的共享保护

我们知道,每个逻辑段对应存在一个程序单位,所以就存在某一个进程的一个段号与另一个进程的段号对应同一段首址和段长度。

一个进程的段号是连续的,但是段与段之间是不一定连续的。

也因为存在这种共享的段,所以也就会有共享段的访问权限规则。

为了实现段的共享和保护,所以我们会对共享段添加一个访问权限栏,对系统增加一个共享段表。
段的共享与保护

段页式存储管理


内存划分与页式管理相同,进程空间划分与段式存储管理相同。
段页式

进程与内存空间的对应关系:进程空间的一个逻辑页面对应内存空间的一个页框,同一段内的逻辑页面是连续的,但对应的页框未必连续。

为了实现映射,我们使用段表记录各段的页表长度与页表首址,页表记录一段中各个逻辑页号与页框号的对应关系,还有段表首址寄存器段表长度寄存器以及快表(保存段表和页表中的部分项目)
段页式快表

段表和页表

地址映射:
段页式地址映射

原创粉丝点击