操作系统--虚拟内存

本文深入探讨了虚拟内存的工作原理,包括其在进程初始化时的内存分配、虚拟地址到物理地址的转换过程。虚拟内存为每个进程提供独立的地址空间和内存保护,并通过页表和TLB加速地址翻译。当访问未缓存的虚拟页时,会发生缺页,此时操作系统会将页面从磁盘加载到物理内存。此外,文章还提及进程页表和Linux系统下进程内存分配的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.前言

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

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

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

二.详细介绍

2.1 简介

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

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

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

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

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

2.2 如何工作
在这里插入图片描述

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

2.3 名词解释

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

2.3.1 地址空间

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值