虚拟内存的作用及实现原理

什么是虚拟地址?

我们实际用到的物理地址就是主存,但是物理主存空间有限,所以一般现代操作系统都会想办法把一部分内存块放到磁盘中,用到的时候再装入主存,但是对用户程序而言,是不需要注意实际的物理内存的,为什么呢?因为有虚拟内存的机制。

让操作系统为每个进程都分配一个虚拟地址,互不干涉。这样每个进程都不能访问物理地址,而是通过访问虚拟地址去映射到物理地址

操作系统会提供一种机制,将不同进程的虚拟地址和不同内存的物理地址映射起来。

一个进程最终要访问到哪个物理内存,由操作系统来管理

这里也引入两个概念

  • 我们程序所使用的内存地址叫做虚拟内存地址
  • 实际存在硬件里面的空间地址叫物理内存地址

进程持有的虚拟地址会通过CPU芯片中的内存管理单元(MMU)的映射关系来转换变成物理地址,然后在通过物理地址去访问内存

image-20240726094002764

那操作系统怎么处理两者关系呢?引入了 内存分段和内存分页

内存分段

程序就是由若干个逻辑分段组成的,如可由代码分段、数据分段、栈段、堆段组成。不同的段是有不同的属性的,所以就用分段的形式把这些段分离出来

image-20240726094457415

  • 段选择子就保存在段寄存器里面。段选择子里面最重要的是段号,用作段表的索引。段表里面保存的是这个段的基地址、段的界限和特权等级等。
  • 虚拟地址中的段内偏移量应该位于 0 和段界限之间,如果段内偏移量是合法的,就将段基地址加上段内偏移量得到物理内存地址。

我们知道分段的方法后,我们可以引入一个实例看一下:

先找到段基地址,然后加上偏移量。就可以正确的对应到物理内存中的地址了

image-20240726094624502

这就是内存分段的方法,但是内存分段有缺点吗?

  • 会产生 内存碎片 的问题
  • 会产生 内存交换的效率低 的问题

探讨一下内存碎片问题

内存碎片分为 内部内存碎片和外部内存碎片:

  • 内部内存碎片:已分配但是未使用的内存。就比如分配了8kb,但是程序只需要用6kb,空闲了2kb
  • 外部内存碎片 :系统中存在的未分配未使用的内存。就比如需要6kb的,但是只有2kb,4kb,5kb的空闲块,虽然总内存是够得,但是因为不连续仍然没法使用

那内存分段会出现内存碎片吗?

内存分段管理会根据实际需求分配内存,所以不会产生内部内存碎片

但是因为每个段长度不固定,多个段未必能恰好使用所有空间,所以会出现外部内存碎片

探讨一下,内存交换效率低问题

因为上面说的容易产生外部内存碎片,那产生这种问题后,不得不进行Swap内存区域,这个过程就会产生性能瓶颈了

Swag是一种辅助内存管理机制,用于扩展系统的可用内存容量。当物理内存不足以满足进程需求时,会将不常用的内存页临时移动到swag区域,以释放足够的武林内存给当前需要的进程。因为swag位于磁盘上,所以读取速度远低于内存。

所以,如果内存交换的时候,交换的是一个占内存空间很大的程序,这样整个机器都会显得卡顿。

针对这两个问题,又引入了内存分页机制

内存分页

要解决上述问题,关键在于减少内存碎片的出现。

采用内存分页,将整个虚拟和物理内存空间切成一段段固定尺寸的大小。

image-20240726103521103

分页具体是怎么解决问题的?

内存分页由于内存空间都是预先划分好的,也就不会像内存分段一样,在段与段之间会产生间隙非常小的内存,这正是分段会产生外部内存碎片的原因。而采用了分页,页与页之间是紧密排列的,所以不会有外部碎片。

但是,因为内存分页机制分配内存的最小单位是一页,即使程序不足一页大小,我们最少只能分配一个页,所以页内会出现内存浪费,所以针对内存分页机制会有内部内存碎片的现象。

如果内存空间不够,操作系统会把其他正在运行的进程中的「最近没被使用」的内存页面给释放掉,也就是暂时写在硬盘上,称为换出Swap Out)。一旦需要的时候,再加载进来,称为换入Swap In)。所以,一次性写入磁盘的也只有少数的一个页或者几个页,不会花太多时间,内存交换的效率就相对比较高。

而且,我们在加载程序的时候,不需要把程序都加载到物理内存中。我们可以都缓冲在虚拟内存中,当真正需要用到的时候,在加载到物理内存中

多级页表

如果使用单一的页面会造成 页表占用特别大的内存空间。

首先我们要知道:页表必须要涵盖所有虚拟地址空间,不然如何虚拟地址在页表中找不到对应的页表项的时候,计算机系统就会停止工作了。

所以我们可以引入多级页面。

以两级页表为例子,第一级页表可以用来存储二级页表的目录,而第二级页表再用来存储实际的数据。

TLB

多级页表虽然解决了空间上的问题,但是由于虚拟地址到空间地址中间多道转换工序,也带来了时间上的开销

为了解决时间问题,在CPU芯片中,加入了一个专放程序最常访问的页表项的Cache,这个Cache就是TLB,通常被称为页表缓存、快表等。

这样以后CPU在寻址的时候,会先查看TLB,如果没查到,在去进行常规的页表检查

分页机制下,虚拟地址和物理地址之间如何映射的?

虚拟地址分为页号页内偏移量,根据页号去页表中寻找对应的物理页号,拿到物理页号后加上前面上偏移量,就找到了物理内存

image-20240726104137649

这种简单的分页会造成空间上的缺陷。页表会占用大量内存

段页式内存管理

将内存分段和内存分页组合起来使用,通常就被称为 段页式内存管理

  • 先将程序划分为多个有逻辑意义的段,也就是前面提到的分段机制
  • 接着再把每个段划分为多个页,也就是对分段划分出来的连续空间,再划分固定大小的页

这样,地址结构就由段号、段内页号和页内位移三部分组成。

那这访问到物理地址的过程是如何的呢?

  • 先访问段表,得到页面起始地址
  • 接着访问页面,得到物理页号
  • 最后将物理页号与页内位移组合,得到了物理地址

image-20240726105711964

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值