页表机制

分页转换功能由驻留在内存中的表来描述,该表称为页表(page table),存放在物理地址空间中。页表可看做简单的2^20个物理地址数组。逻辑地址到物理地址的映射功能可以简单地看做进行数组查找。线性地址的高20位构成这个数组的索引值,用于选择对应页面的物理(基)地址。逻辑地址的低12位给出了页面中的偏移量,加上页面的基地址最终形成对应的物理地址。由于页面基地址对齐在4K边界上,因此页面基地址的低12位肯定是0。这意味着高20位的页面基地址和12位偏移量连接组合在一起就能得到对应的物理地址。(查页表只是想知道高20位地址,逻辑地址中的低12位地址就是物理地址的低12地址)

页表中每个页表项的大小为32位。由于只需要其中的20位来存放页面的物理基地址,因此剩下的12位可用于存放诸如页面是否存在等的属性信息。如果线性地址索引的页表项被标注为存在的,则表示该项有效,我们可以从中取得页面的物理地址。如果页表项中信息表明(说明、指明)页不存在,那么当访问对应物理页面时就会产生一个异常。

1.两级页表结构

页表含有2^20(1M)个表项,而每项占用4Byte(32位)。如果作为一个表来存放的话,它们最多将占用4MB的内存。因此为了减少内存占用量,80x86使用了两级表。由此,高20位线性地址到物理地址的转换也被分成两步来进行,每步使用(转换)其中的10bit。

第一级表称为页目录(page directory)。它被存放在1页4K页面中,具有2^10(1K)个4B长度的表项。这些表项指向对应的二级表。线性地址的最高10位(位31~22)用作一级表(页目录)中的索引值来选择2^10个二级表之一。

第二级表称为页表(page table),它的长度也是1个页面,最多含有1K个4B的表项。每个4B表项含有相关页面的20位物理基地址。二级页表使用线性地址中间10位(位21~12)作为表项索引值,以获取含有页面20位物理基地址的表项。该20位页面物理基地址和逻辑地址中的低12位(页内偏移)组合在一起就得到了分页转换过程的输出值,即对应的最终物理地址。

图4-17给出了二级表的查找过程。其中CR3寄存器指定页目录表的基地址。逻辑地址的高10位用于索引这个页目录表,以获得指向相关第二级页表的指针。逻辑地址中间10位用于索引二级页表,以获得物理地址的高20位。逻辑地址的低12位直接作为物理地址低12位,从而组成一个完整的32位物理地址。

(点击查看大图)图4-17  线性地址和物理地址之间的变换

2.不存在的页表

使用二级表结构,并没有解决需要使用4MB内存来存放页表的问题。实际上,我们把问题搞得有些复杂了。因为我们需要另增一个页面来存放目录表。然而,二级表结构允许页表被分散在内存各个页面中,而不需要保存在连续的4MB内存块中。另外,并不需要为不存在的或逻辑地址空间未使用部分分配二级页表。虽然目录表页面必须总是存在于物理内存中,但是二级页表可以在需要时再分配。这使得页表结构的大小对应于实际使用的逻辑地址空间大小。

页目录表中每个表项也有一个存在(present)属性,类似于页表中的表项。页目录表项中的存在属性指明对应的二级页表是否存在。如果目录表项指明对应的二级页表存在,那么通过访问二级表,表查找过程第2步将同如上描述继续下去。如果存在位表明对应的二级表不存在,那么处理器就会产生一个异常来通知操作系统。页目录表项中的存在属性使得操作系统可以根据实际使用的线性地址范围来分配二级页表页面。

目录表项中的存在位还可以用于在虚拟内存中存放二级页表。这意味着在任何时候只有部分二级页表需要存放在物理内存中,而其余的可保存在磁盘上。处于物理内存中页表对应的页目录项将被标注为存在,以表明可用它们进行分页转换。处于磁盘上的页表对应的页目录项将被标注为不存在。由于二级页表不存在而引发的异常会通知操作系统把缺少的页表从磁盘上加载进物理内存。把页表存储在虚拟内存中减少了保存分页转换表所需要的物理内存量。


查看电脑支持的最大内存数

1.win +R,输入cmd,进入控制台。    输入:wmic memphysical get maxcapacity
在这里插入图片描述

得到的单位是kb,33554432/1024/1024=32G。 所以本电脑支持的最大内存数为32G.
查看电脑有几个卡槽,已经用了几个卡槽

1.在底部的导航栏右键,选择-- 任务管理器
2.选择–性能

如图可以看出,总内存为8g,又两个卡槽,且两个卡槽都使用了,想要扩容的话,只能换内存条,不能增加内存条了。


虚拟内存

第一阶段:没有内存抽象

没有内存抽象对于内存的管理通常非常简单,除去操作系统所用的内存之外,全部给用户程序使用。或是在内存中多留一片区域给驱动程序使用,如图1所示。

图1. 没有内存抽象时,对内存的使用

第一种情况操作系统存于RAM中,放在内存的低地址,第二种情况操作系统存在于ROM中,存在内存的高地址,一般老式的手机操作系统是这么设计的。

如果这种情况下,想要操作系统可以执行多进程的话,

缺陷:多线程直接操作内存,会产生冲突。唯一的解决方案就是和硬盘搞交换,当一个进程执行到一定程度时,整个存入硬盘,转而执行其它进程,到需要执行这个进程时,再从硬盘中取回内存,只要同一时间内存中只有一个进程就行,这也就是所谓的交换(Swapping)技术。

第二阶段:内存抽象——为了解决多线程

内存抽象允许每个进程拥有自己的地址。这还需要硬件上存在两个寄存器,基址寄存器(base register)界址寄存器(limit register),第一个寄存器保存进程的开始地址,第二个寄存器保存上界,防止内存溢出。

问题1:内存大小不可能容纳下所有并发执行的进程。

解决方法:交换(Swapping)。和前面所讲的交换大同小异,交换的基本思想是,将闲置的进程交换出内存,暂存在硬盘中,待执行时再交换回内存,比如下面一个例子,当程序一开始时,只有进程A,逐渐有了进程B和C,此时来了进程D,但内存中没有足够的空间给进程D,因此将进程B交换出内存,分给进程D。如图2所示。

图2. 交换技术

问题2:如图2,进程D和C之间的空间由于太小无法另任何进程使用,这也就是所谓的外部碎片

解决方法:比如内存整理软件,原理是申请一块超大的内存,将所有进程置换出内存,然后再释放这块内存,从而重新加载进程,使得外部碎片被消除。这也是为什么运行完内存整理会狂读硬盘的原因。

问题3:创建进程时分配多少内存。如果分配多了,会产生内部碎片,浪费了内存,而分配少了会造成内存溢出。

解决方法:一种是直接多分配一点内存空间用于进程在内存中的增长,另一种是将增长区分为数据段和栈(用于存放返回地址和局部变量),如图3所示。

图3. 创建进程时预留空间用于增长

当预留的空间不够满足增长时,操作系统首先会看相邻的内存是否空闲,如果空闲则自动分配,如果不空闲,就将整个进程移到足够容纳增长的空间内存中,如果不存在这样的内存空间,则会将闲置的进程置换出去。

问题4:操作系统如何管理内存

法I:位图。将内存划为多个大小相等的块,比如一个32K的内存1K一块可以划为32块,则需要32位(4字节)来表示其使用情况,使用位图将已经使用的块标为1,位使用的标为0.

法II:链表。将内存按使用或未使用分为多个段进行链接,如下图中的P表示进程,从0-2是进程,H表示空闲,从3-4表示是空闲。

图4. 位图和链表表示内存的使用情况

使用位图表示内存简单明了,但一个问题是当分配内存时必须在内存中搜索大量的连续0的空间,这是十分消耗资源的操作。相比之下,使用链表进行此操作将会更胜一筹。

当利用链表管理内存的情况下,创建进程时分配什么样的空闲空间也是个问题。通常情况下有如下几种算法来对进程创建时的空间进行分配。

  • 临近适应算法(Next fit)—从当前位置开始,搜索第一个能满足进程要求的内存空间
  • 最佳适应算法(Best fit)—搜索整个链表,找到能满足进程要求最小内存的内存空间
  • 最大适应算法(Wrost fit)—找到当前内存中最大的空闲空间
  • 首次适应算法(First fit) —从链表的第一个开始,找到第一个能满足进程要求的内存空间

第三阶段:虚拟内存(Virtual Memory)——为了解决大进程的内存要求

在早期的操作系统曾使用覆盖(overlays)来解决这个问题,将一个程序分为多个块,基本思想是先将块0加入内存,块0执行完后,将块1加入内存。依次往复,这个解决方案最大的问题是需要程序员去程序进行分块,这是一个费时费力让人痛苦不堪的过程。

虚拟内存的基本思想是,每个进程有用独立的逻辑地址空间,内存被分为大小相等的多个块,称为页(Page).每个页都是一段连续的地址。对于进程来看,逻辑上貌似有很多内存空间,其中一部分对应物理内存上的一块(称为页框,通常页和页框大小相等),还有一些没加载在内存中的对应在硬盘上,如图5所示。

图5. 虚拟内存和物理内存以及磁盘的映射关系

由图5可以看出,虚拟内存实际上可以比物理内存大。当访问虚拟内存时,会访问MMU(内存管理单元)去匹配对应的物理地址(比如图5的0,1,2),而如果虚拟内存的页并不存在于物理内存中(如图5的3,4),会产生缺页中断,从磁盘中取得缺的页放入内存,如果内存已满,还会根据某种算法将磁盘中的页换出。

MMU中存储页表,用来匹配虚拟内存和物理内存。页表中每个项通常为32位,即4byte,除了存储虚拟地址和页框地址之外,还会存储一些标志位,比如是否缺页,是否修改过,写保护等。因为页表中每个条目是4字节,现在的32位操作系统虚拟地址空间是2^32,假设每页分为4k,也需(2^32/(4*2^10))*4=4M的空间,为每个进程建立一个4M的页表并不明智。因此在页表的概念上进行推广,产生二级页表,虽然页表条目没有减少,但内存中可以仅仅存放需要使用的二级页表和一级页表,大大减少了内存的使用。

每个进程有4GB的虚拟地址空间,每个进程自己的一套页表。程序中使用的都是4GB地址空间中的虚拟地址。而访问物理内存,需要使用物理地址。

一个页表的大小为4K字节,页表项(PTE, page table entry)的大小为4个字节(32bit),所以一个页表中有1024个页表项。

  • 二级页表中的每一项的内容高20bit用来放一个物理页的物理地址,低12bit放着一些标志。
  • 一级页表中的每一项的内容高20bit用来放一个二级页表的物理地址,低12bit放着一些标志。

CPU把虚拟地址转换成物理地址:一个虚拟地址,大小4个字节(32bit),分为3个部分:第22位到第31位这10位(最高10位)是页目录中的索引,第12位到第21位这10位是页表中的索引,第0位到第11位这12位(低12位)是页内偏移。一个一级页表有1024项,虚拟地址最高的10bit刚好可以索引1024项(2的10次方等于1024)。一个二级页表也有1024项,虚拟地址中间部分的10bit,刚好索引1024项。虚拟地址最低的12bit(2的12次方等于4096),作为页内偏移,刚好可以索引4KB,也就是一个物理页中的每个字节。

页面替换算法:物理内存是极其有限的,当虚拟内存所求的页不在物理内存中时,将需要将物理内存中的页替换出去,选择哪些页替换出去就显得尤为重要。

  • 最佳置换算法(Optimal Page Replacement Algorithm):将未来最久不使用的页替换出去,这听起来很简单,但是无法实现。但是这种算法可以作为衡量其它算法的基准。
  • 最近不常使用算法(Not Recently Used Replacement Algorithm):这种算法给每个页一个标志位,R表示最近被访问过,M表示被修改过。定期对R进行清零。这个算法的思路是首先淘汰那些未被访问过R=0的页,其次是被访问过R=1,未被修改过M=0的页,最后是R=1,M=1的页。
  • 先进先出页面置换算法(First-In,First-Out Page Replacement Algorithm):淘汰在内存中最久的页,这种算法的性能接近于随机淘汰。并不好。
  • 改进型FIFO算法(Second Chance Page Replacement Algorithm):这种算法是在FIFO的基础上,为了避免置换出经常使用的页,增加一个标志位R,如果最近使用过将R置1,当页将会淘汰时,如果R为1,则不淘汰页,将R置0.而那些R=0的页将被淘汰时,直接淘汰。
  • 时钟替换算法(Clock Page Replacement Algorithm):虽然改进型FIFO算法避免置换出常用的页,但由于需要经常移动页,效率并不高。因此在改进型FIFO算法的基础上,将队列首位相连形成一个环路,当缺页中断产生时,从当前位置开始找R=0的页,而所经过的R=1的页被置0,并不需要移动页。
  • 最久未使用算法(LRU Page Replacement Algorithm):LRU算法的思路是淘汰最近最长未使用的页。这种算法性能比较好,但实现起来比较困难。

MMU如何将逻辑地址转化为物理地址

1. 段, 大页, 小页, 极小页的划分

4种映射长度:段(1MB)、大页(64KB)、小页(4KB)、极小页(1KB)。

ok, 以这个为前提, 我们设计mmu 两级页表的方式。

假设, 需要寻址 0x12345678这个虚拟地址。

已知它对应的页是0x56789000页,  即真实的物理地址为0x56789678。

我们考虑二级页表该如何设计。

以二级页表方式寻址。

将0~4G空间 4K 一页为单位, 分成1024*1024个页。

256个页组成1M 称之为段。(Section)

4K 的大小为0x0 1000

1M 的大小为0x10 0000

4K 一页, 分页后

0x0000 0000

0x0000 1000

0x0000 2000

0x0000 3000

....

1M 一段, 分段后

0x0000 0000

0x0010 0000

0x0020 0000

0x0030 0000

0x0040 0000

....

共计4096个段,

故虚拟地址前12字节, 0x123 可以作为段的寻址序号。

即以及页表的第0x123个就是我要找的段地址页表。

这个页表在哪里,  首先需要找到段页表地址的基地址, 这个存在cp15协处理器的某个寄存器中(CR3)

ok, 读取段页表基地址, 假设是0xC100 0000, 其中每个页表项是32位整数, 即4byte

所以, 寻找到第0x123个页表项(注意是个,由于每个页表是32bit,4byte 所以就要乘以2^2), 地址为 0xC100  0| 0100 | 1000 | 1100, 即为 0xC100 048C

ok, 找到一级段地址页表项了。 我们就能找到实际的映射的段物理地址了。 是0xC100 048C中存放的32位数中,

我们想想这个32位段页表项该存放写什么??

没错, 要存放二级页表的基地址。 假设是0xC300 0000....

ok, 二级页表项的具体位置该如何明确呢??

先说结论, 虚拟地址的第12位到第19位这8位数据就是页表项的序号。

1). 二级页表应该有256个。

2). 前12位0x123为段地址的序号。

3). 中间8位0x45是页表项的序号。

中间8位数字, 刚好可以表示0x00 ~ 0xFF共256个页表项目的序号

ok, 我们找到0xC300 0000的第0x45号页表项。

里面存放这最终的物理页地址。即0x56789000页, 该页表的基地址为就是0x56789

总共5字节,  即20位数据。

ok, 最后12位数据为真实的页偏移地址/序列号。

故拼接最终的物理地址, 0x56789678。

寻址成功。

https://www.cnblogs.com/xuanyuan/archive/2020/05/15/12894711.html

https://www.cnblogs.com/arnoldlu/p/8087022.html


32位,64位系统寻址空间及最大内存

要看soc芯片能支持最大的内存空间,就看最多可以支持多少地址位,比如可能支持52bit,46bit等,就说明物理地址可以大于4G

理论上:32位=2^32B = 4 * 2^30B = 4GB,这是 32 位下单进程内存上限

目前(2015年5月),Intel的32位架构下,可使用的地址线是36个,可使用的最大物理地址是2^36B,折合64GB,可用的地址空间是4GB。

64位架构下,地址线是46个,所以最大的物理地址是2^46B,折合64TB,可用地址空间也是这么大(目前为止):

为什么32位Windows中实际可用内存少于4G:

虽然物理地址有4G,但CPU如果要访问你的显卡上的显存,就必须把物理地址空间的一部分用于标识显存,这种技术被称为memory-mapped I/O,这样可以让CPU操作显存像操作内存一样。

在Windows的设备管理器里,查看显卡的属性页里的“资源”,可以看到内存映射的地址范围,实际上不管32位还是64位,都需要占用一部分地址空间,32位Windows只有4G的地址空间,被显存占去了一部分,所以可用的地址空间就少于4G了

实际上不仅仅是显存,你电脑上的PCI控制器,各种网卡、声卡、USB控制器等等都需要占用一定的物理内存,所以最终的后果就是可用的物理地址范围变得特别少,最少可能只有1.99GB,这种限制在32位Windows上是不可改变的。

逻辑地址,页表,mmu等相关推荐

  1. 【操作系统/OS笔记05】非连续内存分配:分段、分页、页表

    本次笔记内容: 4.1 非连续内存分配:分段 4.2 非连续内存分配:分页 4.3 非连续内存分配:页表 文章目录 为什么需要非连续内存分配 非连续分配的优劣 分段(segment) 分段寻址方案 分 ...

  2. 操作系统-逻辑地址转换为物理地址Java实现

    输入一个16进制的逻辑地址 转换为物理地址 页表大小可选: 1K 2K 4K 8K 16K 页号 页块 0 5 1 2 2 10 3 11 4 8 程序逻辑: 绝对地址 = 页块×页表大小+偏移量(页 ...

  3. 简述Linux虚拟内存管理

    原文地址:https://cloud.tencent.com/ developer/article/1157420 虚拟存储 虚拟存储(virtual memory, VM)的基本思想是: 维护一个虚 ...

  4. 操作系统 内存管理相关知识

    cpu执行程序的基本过程 译码器 输入为n管脚,输出为2^n根管脚,编号为从0到2^(n-1),用少的输入端控制更多的输出端 最常用的是三八译码器 AD(Address bus)地址总线: 选中一行数 ...

  5. 清华教授的操作系统-----课程笔记

    文章目录 操作系统 准备 系统调用 计算机体系结构及内存分层体系 地址空间 & 地址空间是如何生成的 MMU 连续内存分配 内存碎片问题 分区的动态分配 压缩式碎片整理 交换时碎片整理 **非 ...

  6. 四、地址空间与内存分配

    地址空间 1.地址空间分为物理地址空间和逻辑地址空间. 物理地址空间和硬件直接对应,如内存条代表的主存,硬盘代表的磁盘 ,都是物理内存,其管理由硬件完成 逻辑地址空间是运行的程序看到的地址空间,是一维 ...

  7. Linux Ext 文件系统

    引言 本文整理了 Linux 内核中 Ext 文件系统的相关知识.更多相关文章和其他文章均收录于贝贝猫的文章目录. 文件系统种类 前面我们讨论了虚拟文件系统,它对所有下层文件系统进行了封装,统一了上层 ...

  8. 操作系统读写者问题实验报告_什么是操作系统?

    什么是操作系统? 为什么说C / C++ 更底层 ? 电脑里只有一个CPU, 多线程是怎么实现的 ? 一些简单口胡, 也算对本学期的学习做一个总结 一言蔽之, 操作系统是管理下层硬件, 为上层软件提供 ...

  9. 阅读笔记--操作系统(清华大学公开课)

    B站 https://www.bilibili.com/video/av6538245?from=search&seid=15415472580385966467 练习 在uCore操作系统上 ...

  10. Linux 进程管理与调度

    引言 本文整理了 Linux 内核中进程管理与调度的相关知识.更多相关文章和其他文章均收录于贝贝猫的文章目录. 进程管理与调度 现代操作系统都能同时运行多个进程,至少从用户的角度来看是这个样子的.每一 ...

最新文章

  1. 学以致用七---Centos7.2+python3.6.2+django2.1.1 --搭建一个网站(补充)
  2. Docker Caffe部署
  3. 【性能优化】 之 10053 事件
  4. 【华为云技术分享】解析数据治理在过程可信变革中的运作流程
  5. git 提交代码到新的库,不保留原来的提交历史记录
  6. java 权限管理与用户角色权限设计
  7. cobbler之详细配置
  8. python class是什么_python中什么是类
  9. extjs 教程 java_ExtJS6.2学习
  10. php 写聊天室源码,PHP实现简单聊天室(附源码)_PHP
  11. 详细解说iexplore.exe
  12. 嵌入式软件开发学习路线
  13. OJ 1038 宋小胖买切糕
  14. python 中chr_python中chr
  15. 【雅思】雅思备考教材推荐--个人收集汇总
  16. 特征提取算法_基于特征选择与特征提取融合的鸡蛋新鲜度光谱快速检测模型优化...
  17. poj1737 Connected Graph(计数,组合数学,递推,高精)
  18. 强化学习在智能交通灯中的应用
  19. 2021-08-30物联网控制技术(1)
  20. VMware12卸载之后安装其他版本导致回滚操作的解决方法之一

热门文章

  1. 网站都变成灰色了,这其中代码是怎么实现的?(发现文章,记录保存方便查看)
  2. 题解:UVA1723 Intervals
  3. OSChina 周五乱弹 ——胸这么小!一定是女装程序员
  4. PHP微信小程序/抽奖小程序开源源码
  5. vwap 公式_时间加权平均价格算法(TWAP)和成交量平均算法(VWAP)在量化回测的应用...
  6. WIN8操作系统 使用测评(汪泳)
  7. C++十六进制转八进制
  8. 蓝桥杯C语言 十六进制转八进制
  9. 昨晚上去踢球了,膝盖疼的利害。
  10. YourUninstaller注册码(可用)