【笔记】图说Linux下的虚拟内存寻址、页表

前言

很多地方都需要了解虚拟内存、内存寻址、页表、页表项这些概念,今天集中总结一下:

我们以一台32位计算机,4G内存来讲:

首先要了解这些

虚拟地址空间、虚拟内存技术

现代处理器采用的是虚拟地址寻址的方式,也就是平时访问的内存地址其实都是虚拟地址,需要由操作系统和CPU硬件翻译成物理地址,才能访问该地址的值;

采用这种方式的原因:

  • 如果应用程序可以直接访问物理内存,寻址物理内存的每一个细节,容易破坏操作系统;

  • 再者,如果要运行多个进程,理想状态下是各个进程所占物理内存互不干扰,但谁也无法保证程序没有BUG,如果误操作到其他进程,就会导致程序出现运行问题;

    当然也是有解决方案的,比如限定进程的内存访问界限,但这样会带来额外的寻址开销,这里不展开;

  • 且不管进程间的内存干扰,每个进程都占据一部分内存,就会导致内存不足;

    这里同样也有一些解决方案,比如手动覆盖技术、自动交换技术等,当然也同样存在各自的缺陷,这里也不细究;

那么为了解决上述问题,就有了虚拟内存技术,也成为了现代处理器内存寻址的解决方案;

虚拟内存地址空间被分成多个块,每块都有连续的地址空间,可以被分给应用程序;物理空间也同时被分成很多快,这些块大小和虚拟地址空间的块大小一致;系统会自动将虚拟地址空间映射到物理地址空间;进程只需要请求和操作虚拟内存,从每个进程的角度来看,内存中只存在操作系统内核以及本进程,自己独占了整个内存。我们先不管图里的内存分区。

在这里插入图片描述

虚拟内存技术拥有自动覆盖技术和自动交换技术,使得能够运行比当前空闲内存空间还要大的程序,并借助外存获得更多的空闲内存空间;这里不细究

虚拟内存技术下CPU是如何寻址的

本文以32位处理器,4GB内存来说;

先了解这么一些术语/概念,我尽量全文保持一致:

寻址空间/寻址能力

寻址空间指的是CPU对于内存寻址的能力,寻址空间大小也就是能用到多少内存,对于32位处理器,可以理解成可访问内存地址是2进制的32位,那么我们能访问的地址写成十六进制就有:0x0000 00000x0000 00010x0000 00020xffff ffff,一共232个地址,而每个地址对应的数据是一个字节(1B),那么能用到的内存一共就是232*1B也就是4GB,即寻址空间大小为4GB;

在这里插入图片描述

页表及相关概念

注:本文以一级页表为例,理解了一级页表也就好理解多级页表了

由于应用程序使用的内存地址是虚拟地址,为了能够将其与实际的物理内存达成一个映射,就需要一个表将虚拟地址映射到实际的物理内存地址,这个表就叫做页表,是存储在主存(RAM)里的。页表中的元素就叫做页表项,即虚拟地址与物理地址的映射,具体一点,我们直接看图,以区分开页表、页表项、虚拟地址与物理地址:

在这里插入图片描述

虚拟地址:也就是应用看到的内存地址,在本文就是一个4B(32bit)的地址,分为索引值VPN(Virtual Page Number)和页面偏移量,页面偏移量位数由页大小(page size)决定,Linux默认页大小为4KB,我理解这里的页大小也指的是这页地址所指向的总内存大小,也就是说,一页有4K个内存地址(映射),即212,这样的话,同一页的内存只有后面12位是变化的,前面20位是固定的,如图所示;

物理地址:也就是实际的物理内存地址,和虚拟地址的划分一致,分为PFN(Page Frame Number)和页面偏移量,页面偏移量同样由页大小决定,在默认的4KB页大小下,同样是12位的偏移量和20位的PFN;

所以说,页表其实就是要VPN到PFN的映射;

页表:页表存储着的其实是VPN到PFN的映射,是以array的形式连续存储的,所以VPN作为索引值是隐含在其中的,无需存储在页表中,只需要知道页表的基地址即可,这点类似数组和其下标的关系。系统根据虚拟地址的VPN和页表基地址,即可查到对应的PFN,而虚拟地址的page offset就是对应物理地址的offset,PFN+offset,就得到了虚拟地址对应的物理地址。

页表项:即页表中存储的元素,带有VPN、PFN之间的映射关系以及其他信息(是否缺页标志位、保护位、修改位、访问位和高速缓存禁止位…);由于page size变化会导致VPN和PFN的位数发生变化,所以表项大小其实是不确定的,具体情况具体对待;

注:有些资料中提到页表项大小至少要3B,实际要4B,实际上是在默认的4KB的page size下讲的,因为页大小为4KB时,VPN和PFN就是20bit,也就至少需要3B的内存来存储,但为了方便页表查询,会让一个页表项多占一个字节,也就是一个页表项占4B内存;这样一来,假设一个程序占用2GB的内存,在4KB的page size下,一共需要划分2GB / 4KB = 512K这么多的页表项,而在这个例子中每个页表项占4B内存,整个页表也就占:512K * 4B = 2MB;

计算过程也写一下:

2GB / 4KB = 2 * 2 ^ 30 B / 4 * 2 ^ 10 B = 2 ^ 19 = 2 ^ 9 * 2 ^ 10 = 512 K

512K * 4B = 2 ^ 11 KB = 2 MB

之前我就是被这个例子整晕的……

多级页表

以上我们说的都是一级页表,此外还有二级、三级页表,能够解决一些一级页表的缺陷,这里就不深究了;懒

结语

学习笔记,有错误或补充请指出;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

WuPeng_uin

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

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

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

打赏作者

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

抵扣说明:

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

余额充值