【操作系统复习】 物理地址虚拟地址

    • 物理地址和虚拟地址的区别
      • 物理地址
      • 逻辑地址
      • 线性地址
    • 为什么要分成物理地址和虚拟地址
      • 物理内存及虚拟内存定义
      • 为什么要有虚拟内存
      • 虚拟内存的实现(可以在页式或段式内存管理的基础上实现)
      • ​ 虚拟技术基本特征:
    • 逻辑地址呢?(我回答虚拟地址就是逻辑地址。。)
    • 虚拟地址转换为物理地址的过程
    • 快表是存储在哪里的

 

物理地址和虚拟地址的区别

操作系统有物理地址、逻辑地址、线性地址(也叫虚拟地址)三种地址

物理地址

在存储器里以字节为单位存储信息,为正确地存放或取得信息,每一个字节单元给以一个唯一的存储器地址,称为物理地址(Physical Address),又叫实际地址或绝对地址。

地址从0开始编号,顺序地每次加1,因此存储器的物理地址空间是呈线性增长的。它是用二进制数来表示的,是无符号整数,书写格式为十六进制数。它是出现在CPU外部地址总线上的寻址物理内存的地址信号,是地址变换的最终结果。用于内存芯片级的单元寻址,与处理器和CPU连接的地址总线相对应。

逻辑地址

逻辑地址是指在计算机体系结构中是指应用程序角度看到的内存单元(memory cell)、存储单元(storage element)、网络主机(network host)的地址。 逻辑地址往往不同于物理地址(physical address),通过地址翻译器(address translator)或映射函数可以把逻辑地址转化为物理地址。

在有地址变换功能的计算机中,访问指令给出的地址 (操作数) 叫逻辑地址,也叫相对地址。要经过寻址方式的计算或变换才得到内存储器中的物理地址。把用户程序中使用的地址称为相对地址即逻辑地址。逻辑地址由两个16位的地址分量构成,一个为段基值,另一个为偏移量。两个分量均为无符号数编码。

线性地址

线性地址(Linear Address)是逻辑地址到物理地址变换之间的中间层。在分段部件中逻辑地址是段中的偏移地址,然后加上基地址就是线性地址。

线性地址是一个32位无符号整数,可以用来表示高达4GB的地址,也就是,高达4294967296个内存单元。线性地址通常用十六进制数字表示,值的范围从0x00000000到0xffffffff)。程序代码会产生逻辑地址,通过逻辑地址变换就可以生成一个线性地址。如果启用了分页机制,那么线性地址可以再经过变换以产生一个物理地址。当采用4KB分页大小的时候,线性地址的高10位为页目录项在页目录表中的编号,中间10位为页表中的页号,其低12位则为偏移地址。如果是使用4MB分页机制,则高10位页号,低22位为偏移地址。如果没有启用分页机制,那么线性地址直接就是物理地址。

为什么要分成物理地址和虚拟地址

物理内存及虚拟内存定义

​ 物理内存是相对于虚拟内存而言的。物理内存指通过物理内存条而获得的内存空间,而虚拟内存则是指将硬盘的一块区域划分来作为内存。内存主要作用是在计算机运行时为操作系统和各种程序提供临时储存。

为什么要有虚拟内存

​ 在早期的计算机中,要运行一个程序,会把这些程序全都装入内存,程序都是直接运行在内存上的,也就是说程序中访问的内存地址都是实际的物理内存地址。当计算机同时运行多个程序时,必须保证这些程序用到的内存总量要小于计算机实际物理内存的大小。 早期内存分配方法实例:

​ 某台计算机总的内存大小是 128M ,现在同时运行两个程序 A 和 B , A 需占用内存 10M , B 需占用内存 110 。计算机在给程序分配内存时会采取这样的方法:先将内存中的前 10M 分配给程序 A ,接着再从内存中剩余的 118M 中划分出 110M 分配给程序 B 。这种分配方法可以保证程序 A 和程序 B 都能运行,但是这种简单的内存分配策略问题很多。如下图:

<https://static.nowcoder.com/images/activity/2021jxy/java/img src=“https://static.nowcoder.com/images/activity/2021jxy/java/img/asset/早期内存分配截图.png” alt=“早期内存分配截图” style=“zoom:80%;” />

​### 早期内存分配方法

​ 早期的内存分配方法存在如下几个问题(为什么要有虚拟内存的原因):

​ 问题 1 :进程地址空间不隔离。由于程序都是直接访问物理内存,所以恶意程序可以随意修改别的进程的内存数据,以达到破坏的目的。有些非恶意的,但是有 bug 的程序也可能不小心修改了其它程序的内存数据,就会导致其它程序的运行出现异常。这种情况对用户来说是无法容忍的,因为用户希望使用计算机的时候,其中一个任务失败了,至少不能影响其它的任务。

​ 问题 2 :内存使用效率低。在 A 和 B 都运行的情况下,如果用户又运行了程序 C,而程序 C 需要 20M 大小的内存才能运行,而此时系统只剩下 8M 的空间可供使用,所以此时系统必须在已运行的程序中选择一个将该程序的数据暂时拷贝到硬盘上,释放出部分空间来供程序 C 使用,然后再将程序 C 的数据全部装入内存中运行。可以想象得到,在这个过程中,有大量的数据在装入装出,导致效率十分低下。

​ 问题 3 :程序运行的地址不确定。当内存中的剩余空间可以满足程序 C 的要求后,操作系统会在剩余空间中随机分配一段连续的 20M 大小的空间给程序 C 使用,因为是随机分配的,所以程序运行的地址是不确定的。

虚拟内存的实现(可以在页式或段式内存管理的基础上实现)

​ (1)在装入程序时,不必将其全部装入到内存,而只需将当前要执行的部分页面或段装入到内存,就可让程序开始执行;

​ (2)在程序执行过程中,如果需执行的指令或访的数据尚未在内存(称为缺页或缺段),则由处理器通知操作系线将相应的页面或段调入到内存,然后继续执订程序;

​ (3)另一方面,操作系统将内存中暂时不用的页面或段调出保存在外存上,从而腾出更多空困空间存放将要装入的程字以及将要调入的页画或段。

​ 虚拟技术基本特征:

大的用户空间(物理内存和外存相结合形成虚拟空间)、部分交换(调入和调出是对部分虚拟地址空间进行的)、不连续性(物理内存分配的不连续,虚拟地址空间使用的不连续)。

逻辑地址呢?(我回答虚拟地址就是逻辑地址。。)

如果是没有使用虚拟内存的页式/段式系统,没有虚拟地址这一说法,
逻辑地址一定直接可以转换为物理地址,因为进程都在内存中存储。
如果是使用了虚拟内存的页式/段式系统,就有虚拟地址了,因为不一定在内存中存储,得到的进程地址不一定能在内存上找到,因为页表上对应的块号可能为空。
至于线性地址,仅存在于段页式,逻辑地址查找段表得到线性地址,线性地址查找页表得到物理地址

这就是 overfitting 32-bit x86 的坏处了,你提到的几个概念有些是 x86 特有的,别的体系结构里没有它,有的在 x86-64 里已经被废弃,不值得细究。

打个比方,你说

中国共产党中央军事委员会

中华人民共和国中央军事委员会

有什么区别?
Linux 线性地址,逻辑地址和虚拟地址的关系? 

虚拟地址转换为物理地址的过程

逻辑地址和虚拟地址是一个意思 叫法不同而已 编译器产生的地址
逻辑(虚拟)地址经过分段转化为线性地址
线性地址经过分页转为物理地址

地址转换流程
按照逻辑地址中的页号查快表
若该页已存在快表中,则由页架号和单元号形成绝对地址
若该页不在快表中,则再查主存页表,与单元号形成绝对地址,同时将该页登记到快表中
当快表填满后,又要登记新页时,则需要按照一定替换策略淘汰一个旧的登记项

快表是存储在哪里的

在操作系统中引入快表是为了加快地址映射速度。
在虚拟页式存储管理中设置了快表,作为当前进程页表的Cache。通常快表处于MMU中(中文名是内存管理单元,有时称作分页内存管理单元)