写点什么

操作系统 -- 虚拟内存

用户头像
en
关注
发布于: 2021 年 07 月 31 日
操作系统--虚拟内存

一.前言

在之前研究进程上下文切换和 golang 内存分配器的过程中,发现虚拟内存在其中都扮演着十分重要的角色,之前有学习和了解过虚拟内存,但是随着时间推移也只知道一个概念,现在想要带着问题去再学习一遍虚拟内存,希望这篇文章也能帮助你们更好的理解虚拟内存。

1.进程初始化的时候是如何分配的内存

2.虚拟内存的具体工作流程

二.详细介绍

2.1 简介

虚拟内存是一个抽象概念,它为每个进程提供了一个假象,即每个进程都在独占的使用主存。每个进程看到的内存都是一致的,称为「虚拟地址空间」

虚拟内存主要提供了三个能力

  • 它将主存看做是一个存储在磁盘上的地址空间的高速缓存,在主存中只保存活动区域,并根据需要在磁盘和主存之间来回传送数据,通过这种方式高效使用了主存

  • 它为每个进程提供了一致的地址空间,简化了内存管理

  • 它保护了每个进程的地址空间不被其他进程破坏

2.2 如何工作

如图所示,cpu 通过生产一个虚拟地址 4001 访问主存,虚拟地址再 mmu 的转换下映射为物理地址中的 2,通过讲翻译后的物理地址传给主存,主存读取从物理地址 2 开始的 4 个字节将其返回给 cpu。

2.3 名词解释

知道了大概的处理流程,接下来讲解一下虚拟内存相关的几个名词。

2.3.1 地址空间

一个非负整数地址的有序集合,在带有虚拟内存的系统中,cpu 从一个有 N=2^n 个地址的地址空间中生成虚拟地址,这个地址空间成为虚拟地址空间,要求是 2 的幂,一般由计算机的位数决定,如 32 位对应 2^32,64 对应 2^64。

物理地址空间则对应的是系统中物理内存的 M 个字节,没有 2 的幂的要求

2.3.1 页表

页表将虚拟页映射到物理页,每次地址翻译硬件将一个虚拟地址转换为物理地址时,都会读取页表,操作系统负责维护页表内容,以及在磁盘与 DRAM(Dynamic Random Access Memory)之间来回传送页。


页面分配的三种情况

页表是一个页表条目(pte:page table entry)的数组,每一条由一个有效位和一个 n 位地址字段组成,有效位表明了该虚拟页是否被缓存在 DRAM,如果有效,那么地址字段就表明了 DRAM 中的物理页起始地址。图中 vp1,vp2,vp4 都是这种情况。

若是空地址,则表明这个虚拟页还没有被分配,vp0 就是这种情况。

若是有地址,但是有效位为 0,那么就表明虚拟页被分配在了磁盘上,地址指向的就是虚拟页在磁盘的起始地址。

缺页

DRAM 缓存不被命中就叫做缺页。

如果我们去访问 vp3,就会发现 vp3 不在 DRAM 中,由于磁盘和 DRAM 的访问速度差了 100000 多倍,那么我们就需要将 vp3 缓存到 DRAM 中,此时我们将 vp3 从磁盘复制到物理内存(如果此时物理内存不够,就按照一定的算法将原本保存在里面的页面移出,并设置页表中对应的标记位为无效),再将 vp3 在页表中对应的 pte 有效位设置为有效,修改地址从磁盘指向 DRAM。

进程页表

虚拟内存为每个进程提供了一个独立页表,因而是一个独立的虚拟地址空间,一来方便用户操作,二来方便用户共享内存,因为不同的页表支持映射到同一个共享物理页面上。

2.4 地址翻译

2.4.1 名词介绍

页表基址寄存器(page table base register PTBR):在 cpu 寄存器中指向当前页表(进程上下文切换中要更换)

n 位虚拟地址:包含一个 p 位的虚拟页面偏移(virtual Page Offset,VPO)和一个 n-p 位的虚拟页号(virtual

page number,VPN),MMU 利用 VPN 来选择适合的 pte。物理页面的偏移量则与虚拟页面一致。

MMU(Memory Management Unit,内存管理单元):用于翻译虚拟地址和物理地址映射关系

2.4.2 地址翻译整体流程


  1. cpu 生成虚拟地址,传递给 MMU

  2. mmu 生成 pte 地址(这一步是 mmu 通过虚拟地址的虚拟页号获取的),并从高速缓存/主存得到它

  3. 高速缓存/主存将 pte 返回给 mmu

  4. mmu 通过页表,构造物理地址,将其传给高速缓存/主存

  5. 高速缓存/主存将请求的数据字给处理器

2.4.3 TLB

由上面的知识,每次获取内存 mmu 都需要去内存取一次 pte,利用缓存思想(设计系统或者提高请求效率的时候都可以往这个上面靠,最基本原理就是空间换取时间),操作系统发明了 tlb(translation lookaside buffer),他是一个关于 pte 的小缓存(注意进程上下文切换也需要清空 tlb)。

有了 tlb,如果发生命中,那么过程如下。

  1. cpu 生成虚拟地址,传递给 MMU

  2. mmu 从 tlb 取出相应的 pte

  3. mmu 将虚拟地址翻译成一个物理地址,并将它发送到高速缓存/贮存

  4. 高速缓存/主存将请求的数据字给处理器

三.问题思考

经过书本的系统学习,我已经了解了虚拟内存的工作原理,解决了问题二,还有进程初始化的时候是如何分配的内存这一问题。

以 linux 为例子,先看看在 linux 系统下进程的虚拟内存结构

进程能获取多少内存主要取决于运行时堆的内存分配,其余的内存消耗都是每个进程必要的,也就是说一个没有跑起来的进程消耗的内存都在物理内存上,等进程跑起来,会由操作系统对进程申请的内存进行动态分配,决定哪些放在物理内存,哪些放在主存,这是我们所不需要感知的。

四.参考文档

深入理解计算机系统

https://www.guru99.com/stack-vs-heap.html


发布于: 2021 年 07 月 31 日阅读数: 20
用户头像

en

关注

努力分享对他人有价值的知识 2018.06.14 加入

还未添加个人简介

评论

发布
暂无评论
操作系统--虚拟内存