页式内存管理

基址极限管理模式的问题

上篇博客分析了几种基本的内存管理模式:固定加载地址的内存管理,固定分区的内存管理,非固定分区的内存管理和交换内存管理。第一种只适合单道编程,后三种是多道编程均使用使用了同一种机制:基址与极限。

基址与极限的工作原理:将程序发出的虚拟地址加上基址而获得的物理地址。如果该地址值超过指定的极限,则视为地址出界禁止访问,否则访问正常进行。

交换内存管理是上述管理中最灵活和先进的。但是其也面对两个重要的问题:空间浪费和程序大小受到限制。

空间浪费---->外部碎片化:内存的剩余的空间虽然大于程序所需空间,但是由于碎片化则导致该程序不能加载到内存上。

程序受限----->交换需要大量进行磁盘和内存之间的交换,效率低下。虽然我们的程序空间可以拓展到磁盘但是我们的程序依旧不能超过物理内存空间(减去操作系统占用的那部分)。

分页内存管理机制

一:解决之道

  我们是否有办法去解决交换所产生的两种问题呢!首先要分析这些问题的根源出现在哪里?空间碎片化的根源就是每个程序的大小不一样,这样在空间分配时不存在一致性。解决的办法自然是将空间按照某种规定的大小进行分配。将虚拟内存和物理内存都分成大小一样的部分,我们称之为“页”。这样可以解决①外部碎片化②程序不需要全部同时加载到内存上。

二:分页内存管理

  核心:将虚拟内存空间和物理内存空间借划分为大小相同的页,并以页作为内存空间划分的最小单位。空间增长也容易实现:只需要分配额外的虚拟页面,并找到一个闲置的物理页面存放即可。

在分页系统的机制下:一个程序发出的虚拟地址由两部分组成:页面号 和 页内偏移值。

三:地址翻译

  分页系统能够工作的前提是:对于任何一个虚拟页面,系统知道该页面是否在物理内存中。如果在的话直接对应,如果不在的话则会产生系统中断(缺页中断),并将该虚拟页从磁盘转到内存,然后分配给他的物理内存页号返回。

内存管理单元(MMU):进行翻译过程-------页面的翻译。

工作原理:MMU接受CPU发出的虚拟地址,将其翻译为物理地址后发送给内存,内存单元按照该物理地址进行相应的访问后读出或写入相关数据。

MMU对虚拟地址的翻译只是对页面号的翻译,即将虚拟页面号翻译成物理页面号。。面对偏移值不做任何操作(都是一样)

如何完成该翻译的?查页表。

1. 对于每一个程序:MMU都为其保存一个页表(该表里面存放虚拟页面到物理页面的映射)。每当为一个虚拟页面寻找到一个物理页面的时间后,就在页表中增加一个记录(页表的增添)。

2.

3.

程序在加载前所使用的一切地址均是虚拟地址,即程序存在虚拟空间。

那么虚拟空间的大小有多大呢?这与系统总线的长度有关。32位寻址的系统虚拟地址空间的大小为2^32 -1,即一个程序最多可以有2^32 -1条指令。但是一个程序的一般没有这么多的指令。所以呢有一部分虚拟空间是空的,即程序没有使用这一部分,这部分的空间就是改程序的非法虚拟地址空间(非法虚拟页面)。虚拟页面非法:虚拟页面不存在

四:页表

页表的根本功能是:提供从虚拟页面到物理页面的映射。因此,页表的记录条数与虚拟页面数相同。例如:对于32位寻址的虚拟地址,页面大小为4KB,则虚拟页面数最多为2^20个虚拟页面数。

MMU依赖页表进行一切与页面有关的管理活动。

缓存禁止位:指示该页面是否允许存放在缓存里。

访问位:记录该页面是否被访问过(读或写)。

修改位:记录该页面自从加载到物理内存上是否被修改过。

保护标识位:记录该页的受保护情况,是否允许读,写,执行。

是否在内存:记录该页是否在物理内存,

保留区:增加扩充该版本的页表的记录项,具体的位置有硬件决定。

小地址存放:前四位为页面号,后12位为页内偏移值。 

分页系统的优缺点

优点:

1.不会产生外部碎片化,一个进程占用的内存空间可以不是连续的,

2.一个进程的虚拟页面在不需要时,可以存放在磁盘上。

3.可以共享小的地址,即页面共享。只要给相应的页表里面做一个相应的记录便可。

缺点:

1.页表很大,占用了大量的内存空间,32为寻址空间页面大小为4KB,页表将会有2^20个。

多级页表

当CPU发出一个虚拟地址时,将这个地址分为三部分:前10位的值作为顶级页表的索引。中间10作为次级页表的索引。最后12位作为页内偏移值。用最前的10位找到顶级页表对应的记录->得到次级页表。------->中间10位作为索引获得所需要的次级页表里对应的物理项----》获得到对应的物理页面号--------》最后12位作为页内的偏移值。

多级页表的缺点:

1.降低了系统的速度,每次的内存访问变成了多次(对于二级页表,变成了三次),如果次级页表不在内存,还需要加上一次磁盘访问。

 地址翻译速度

地址翻译速度因增加了内存访问次数而降低了系统效率。由于内存访问是每条指令都需要执行的操作,造成了系统的效率降低。

那么我们有什么解决的办法呢?:如果一个页面被访问,可能该页面的其他地址也将随后被访问,这样我们可以将该页面的翻译结果存放在缓存里面,而无需在访问该页面的每个地址时在翻译一次。

这种存放翻译结果的缓存称为翻译快表(Translation Look-Aside Buffer),缩写为TLB。TLB存放的是从虚拟页面到物理页面的映射,其记录格式和正常的页表格式相似:

如果TLB里面有该虚拟地址记录,-----》即 命中 直接从TLB中获得该地址对应的物理页面号。如果在TLB中没有的话即未命中

例如(TLB表的使用):

如果CPU发出的虚拟地址属于虚拟页面800,则我们查看TLB表其对应的物理页面号为13。但是我们怎么知道800在TLB表中呢?总不能遍历比较吧!那么我们的使用TLB的本意就没有用处了。

软件没有办法构建原子操作,只能把硬件请出来!我们看到软件没有办法一次将内存访问完成TLB的查找,那么只能吧硬件请出来了:我们在TLB里进行的比较不是一个个的顺序比较,而是同时比较,即将所有的TLB记录与目的虚拟地址同时比较,因此只需要一次查找就能查找完成。而设计需要同时设备多套比较电路,比较电路的套数与TLB的大小一样,这也就是为什么TLB昂贵的原因。

缺页中断处理

定义:在分页虚拟内存管理系统中:一个虚拟页面内存即有可能在物理内存,也有可能在磁盘上。如果CPU发出的虚拟地址对应的页面不在物理内存,就会产生一个缺页中断。

缺页中断的处理步骤:

1.硬件陷入内核。

2.保护通用寄存器。

3.操作系统判断需要的虚拟页面号。

4.操作系统检查地址的合法性。

5.OS选择一个物理页面用来存放将要调入的页面。

6.如果选择的物理页面包含有未写磁盘的内容,则首先进行写盘操作。

7.OS将新的虚拟页面调入内存。

8.更新页表

9.发生缺页中断的程序进入就绪状态

10.回复寄存器

11.程序继续。

页面锁住

如果发生缺页中断,则需要将磁盘上的页面调入到内存上。这就有可能将现有的页面进行替换,页面替换。

但是呢我们需要将页面锁在内存,不想被交换出去。比如包含用于存放输入数据缓冲的页面。那么该页面如何锁住呢?很简单在,只需要将页表的相应记录项增加一项标记即可。

内存抖动

在更换页面时,如果更换的页面是一个很快就会被再次访问的页面,则在此次缺页中断后,很快又会发生新的缺页中断。这样多次在磁盘和内存的切换以及调度时间,整个系统的效率会急剧下降。这种现象就是内存抖动!

猜你喜欢

转载自blog.csdn.net/genzld/article/details/83415508
今日推荐