《现代操作系统》笔记-内存管理2

接上

内存管理

内存抽象的演化过程

3.虚拟内存

使用之前的方法管理内存存在的问题:随着软件的发展,程序变得太大无法放入内存中;或单个程序可以放入,而多个程序一起则无法放入。

解决方法:覆盖技术(overlay)

程序启动时先加载overlay管理模块,它会马上加载程序的overlay0部分。之后覆盖原overlay0(内存中无更多空间),或者在原overlay0的后面(有更多空间),调入overlay1。以此往复。调入调出的操作还是要经过操作系统。

缺点:可以相互覆盖的overlay块需要由程序员来划分,耗时且容易出错。

虚拟内存的基本思想:把程序的地址空间分为叫做页(page)的多块,每个页是一段相邻的地址,这些页对应到物理内存中。在程序运行时,并非所有的页都要调入物理内存中。当程序访问地址空间时,如果访问的页已经在物理内存中,硬件会自动映射;如果不在,则陷入操作系统,将该页调入并重新执行。

每个进程都有自己的地址空间,虚拟内存是一种抽象,让进程感觉自己有足够的内存空间来运行,实际是通过操作系统不断地调入物理内存来实现。

(1)分页

程序生成的地址叫虚拟地址(virtual address),虚拟地址形成的空间叫虚拟地址空间(virtual address space)

在不使用虚拟内存技术时,这些虚拟地址被直接送入内存总线进行读写操作。在使用虚拟内存技术时,它们被送入内存管理单元(Memory Management Unit),将虚拟地址转换为物理地址,再送入内存总线。

虚拟地址空间由大小相同的单元——页组成。在物理内存中对应的部分叫页框(page frame)。页和页框通常大小相同(一般为4KB),在内存和磁盘中的传输以页为单位。页的节点通过映射、未映射位表示是否存在于物理内存中。

如果访问的内存未映射,则MMU使CPU陷入操作系统(缺页中断),操作系统挑选出一个很少使用的页并写回磁盘,置换出来,将页从磁盘中调入页框,并重新执行。

将虚拟地址分为页表入口地址/页号 (高位)偏移地址 (低位),通过页号在页表中找到物理地址中对应的页框,再通过偏移地址找到具体对应的页。在页大小为4K的情况下,只需要12bit的偏移地址就可以表示(内存作为硬件,基本单位是字节byte,212 byte = 4096 byte = 4KB)

(2)页表

页表的作用是对应虚拟页和内存中的页框

页表单个节点的组成:页框号、是否映射标志位、读写保护位、修改位(Modified)、访问位(Reference)、是否缓存位(用于虚拟页映射设备寄存器)

磁盘上保存的未调入内存中的页,不是页表的一部分。因为页表是虚拟地址到物理地址映射的信息,而磁盘上的页是操作系统处理缺页异常的信息,而不是硬件需要的。

从某种角度,虚拟内存是基址-界限寄存器的进一步归纳概括(虚拟内存技术是先根据页框号找到物理内存中的页框,再根据偏移地址找到页)

(3)加速分页

分页系统的两大问题: a.从虚拟地址到物理地址的映射要快; b.随着虚拟地址的增大,页表也要增大。

A. 最简单的策略:由一系列的寄存器组成一张页表,每个虚拟页一个节点,全部放入寄存器中。进程运行时拷贝内存中的页表,调入即可。

优点:运行过程中进程不需要再访问内存中的页表

缺点:当页表非常大时,开销很大;每次上下文切换时载入整个页表,性能很差。

B. 另一种极端策略:页表全部放在内存中,仅有一个寄存器指向它的起始地址

缺点: 执行指令时需要多次访问内存,读取页表

C. 转换检测缓冲区 TLB(Translation Lookaside Buffer) / 快表

观察到的现象:大部分程序运行时访问的内存集中在一小部分页中,即一小部分页表节点被频繁读写,其它则很少。

TLB在MMU中,并由一些节点组成,每个节点包括虚拟页号、修改位、保护码(读、写、执行)、物理页框号、是否使用位。它们与内存中的页表一一对应(页表可以没有“虚拟页号”这一字段)

过程:

虚拟地址被送入MMU时,硬件首先检查虚拟页号是否在TLB中(可以通过特殊的硬件并行比较),如果有就不再查找,读写操作符合保护位的要求则可以继续;如果不在TLB中,则TLB会用新的查找记录取代一条旧的查找记录。当记录从TLB中清除时,修改位会写会内存的页表节点。

只有在要访问的页不在内存中时,才会陷入操作系统。TLB的管理和在TTLB中未找到的问题都由硬件MMU来处理。

软件管理TLB

在RISC的机器中,页的管理由软件进行。

操作系统预知接下来可能被访问的内存,并提前载入TLB。

当TLB的条目足够大时(64条),TLB中找不到的情况就可以减少,由软件管理TLB的效率变得可以接收。而且可以简化MMU,让CPU有更多的空间来放置缓存和其它组件。

软件管理的TLB的问题:放置页表的页不在TLB中,由此会导致额外的TLB缺失错误(页在内存中的情况下)。

硬件管理TLB时,由MMU管理页表,在TLB中找不到对应的页,由MMU在页表中寻找,并更新原条目。软件管理TLB时,在TLB中找不到页,产生一个TLB缺页错误(正常);再去页表中查找,发现存放页表的页也不在TLB中,再次产生TLB缺页错误(额外的)。

解决:

专门维护一个大的页表缓存,保存它们的页一直在TLB中

软失效(soft miss):访问的页不在TLB中,但在内存中 => 更新TLB即可

硬失效(hard miss):访问的页既不在TLB中,又不在内存中 => 从磁盘读取页,更新TLB

其它情况:

a. 页在内存中,但不在当前进程的页表中 => 重新在页表中映射 次要缺页错误(minor page fault)

b. 页必须要从磁盘读入 主要缺页错误 (major page fault)

c.程序访问了非法的地址 => 操作系统以段错误结束进程 段错误(segmentation fault)

(4) 大内存的页表 (管理巨大的虚拟地址空间)

A. 多级页表(Multilevel Page Tables)

32位的虚拟地址被分为10 + 10 + 12(212 = 4KB,一页的大小),则总共会有210 * 210个。

根据不同区段的地址从顶级到低级依次找到对应的页。因为程序所需要的往往不是全部的页,因此分级之后,需要的就是顶级页表和下一级中的几个页表,其余的在顶级页表中用未映射位标识。

B. 反转页表(Inverted Page Tables)

最早被PowerPC,UltraSPARC,Itanium 采用。每个页表节点上对应一个页框,而不是对应虚拟地址空间。4GB的内存需要220个节点。

优点:当虚拟地址空间很大时(64位),可以大大节省页表空间。

缺点:将虚拟地址映射为物理地址时十分困难(没法直接对应),每次访问内存都要遍历页表。

解决:

a. 使用TLB

b. 用HashTable将在内存中映射过的、且hash值相同的虚拟页用hash表节点连起来。如果hash表节点足够多,就相当于页框节点与hash表节点一一对应。

反转页表在64位机器中很常见,因为即使单个页很大,仍然需要大量的页表节点。

posted @ 2019-04-14 22:59  battor  阅读(288)  评论(2编辑  收藏  举报