虚拟内存系统【如何支持巨大的虚拟地址空间】

📖1. 为什么要支持巨大的虚拟地址空间

为什么我们要为进程支持巨大的虚拟地址空间呢

为了方便和易用性,有了巨大的地址空间,你不必担心程序的数据和代码是否有空间存储,只需自然的编写代码,根据需要分配内存.

📖2. 交换空间

我们需要在硬盘上开辟一部分空间用于物理页的移入和移出,在操作系统中,一般这样的空间称为交换空间(swap space).因为我们将内存中的页交换到其中,并在需要的时候又交换回去.

image-20221201111234015

上图中,可以看到一个4页的物理内存和8页的交换空间(在磁盘上),有4个进程,进程0、进程1、进程2都只有一部分有效页在内存中,剩下的在硬盘的交换空间中,进程3的所有页都被交换到了磁盘上,因此它目前没有运行,有一块交换空间是空闲的,通过这个小例子,你应该能够看出,使用交换空间是如何让系统假装比实际物理内存更大.

📖3. 存在位

现在我们在硬盘上有一部分交换空间,需要在系统中增加一些机制,来支持从硬盘交换页.

让我们先回想一下内存引用会发生什么

正在运行的进程生成虚拟地址(用于获取指令或访问数据),硬件将其转换为物理地址,再从内存中获取所需数据.

硬件首先从虚拟地址获得VPN(虚拟页号),检查TLB是否命中,如果命中,则获得最终的物理地址并从内存中取回,它不需要额外的内存访问.

如果在TLB中找不到VPN(即TLB未命中),则硬件在内存中查找页表(使用页表基址寄存器),并使用VPN查找该页的页表项(PTE)作为索引,如果页有效且存在于物理内存中,则硬件从PTE中获得PFN,将其插入TLB,并重试该指令,这次TLB中就会命中.

但是,我们要支持页可以从内存交换到磁盘,必须添加更多的机制,具体的说,当硬件在PTE中查找时,可能发现页面不在物理内存中,硬件判断是否在内存中的方法,是通过页表项中的一条新信息,即存在位.

如果存在位设置为1,则表示该页存在于物理内存中,如果存在位设置为0,则表示该页不在物理内存中,而在硬盘中. 访问不在物理内存中的页,这种行为被称为页错误.

当发生页错误(页未命中),硬件产生中断,操作系统被唤醒处理页错误,执行页错误处理程序.

📖4. 页错误

如果一个页不在物理内存中,即它已经被交换到了硬盘上,在处理页错误时,操作系统需要将该页交换到内存中,那么有一个问题:操作系统怎么知道所需的页在哪里呢?

操作系统可以用PTE中的某些位来存储硬盘地址,把存储PFN的位置改为存储硬盘地址,当操作系统收到页错误时,它会在PTE中查找地址,并将请求发送到硬盘,将页读取到内存中.

当硬盘I/O完成时,操作系统会更新页表,将此页标记为存在,更新页表项(PTE)的PFN字段以记录新获取页的内存位置,并重试指令. 下一次重新访问时TLB还是未命中,然而这次因为页在内存中,因此会将页表中的地址更新到TLB中(也可以在处理页未命中时顺便更新TLB),最终的重试操作会在TLB中找到转换映射,从已转换的内存物理地址,获取所需的数据或指令.

📖5. 为了处理页错误,操作系统大致做了什么?

首先,操作系统必须为将要换入的一个页找到一个物理帧,如果没有这样的物理帧,我们将不得不等待页面置换算法执行,并从内存中踢出一些页,释放帧供这里使用. 在获得物理帧后,处理程序发出I/O请求从交换空间中读取页,最后,当这个慢操作完成时,操作系统更新页表并重试指令,重试将导致TLB未命中,然后硬件(MMU)通过查找页表找到该项并缓存在TLB中,然后再一次重试,此时硬件将能够访问所需的值.

📖6. 页面换出

刚才我们假设有足够的空闲内存来存储从交换空间换入的页. 但是,如果内存已经满了呢?

这时操作系统必须先交换出一个或多个页,以便为操作系统即将交换入的新页留出空间,选择哪些页被换出的策略,被称为页面置换.

📖7. 当程序从内存中读取数据会发生什么?

首先硬件从虚拟地址中拿出VPN,并在TLB中检查是否命中,当TLB未命中时则需要查找页表中的PTE,会分三种情况:

  1. 该页存在且有效,在这种情况下,TLB未命中处理程序可以从PTE中获取PFN,并将这对转换保存在TLB中,接着重新执行指令,这次TLB会命中,获得物理地址并在内存中读取到数据
  2. 页未命中处理程序需要运行,虽然它是一个有效页,但它此时不在物理内存中
  3. 访问的是一个无效页,可能由于程序中出现了错误,硬件捕获这个非法访问,操作系统陷阱处理程序运行,可能会杀死非法进程.

📖8. 页面置换什么时候真正发生

为了保证有少量的空闲内存,大多数操作系统会设置高水位线和低水位线(LW),来帮助决定何时从内存中清楚页.

大致原理是这样:当操作系统发现有少于LW个页可用时,后台负责释放内存的线程会开始运行,直到有HW个可用的物理页,这个后台线程有时称为交换守护进程或页守护进程.

在执行交换的过程时,我们可以进行一些优化,例如,许多系统会把多个要写入的页聚集或分组,同时写入到交换空间中,从而提高硬盘的效率.

为了配合后台的分页线程,页面置换算法首先检查是否有空闲页,而不是直接执行替换,如果没有空闲页,会通知后台的分页线程按需要释放页(把它换出到磁盘上),当线程释放一定数目的页时,它会重新唤醒原来的线程,然后就可以把需要的页换进内存,继续执行.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

沉默.@

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

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

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

打赏作者

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

抵扣说明:

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

余额充值