文章目录

  • 5.1 页表
    • 5.1.1 页表介绍
    • 5.1.2 页表项
  • 5.2 页表结构
    • 5.2.1 多级页表
    • 5.2.2 哈希页表
    • 5.2.3 倒置页表
  • 5.3 快表
    • 5.3.1 局限性原理
    • 5.3.2 快表机制
    • 5.3.3 访问速率
  • 5.4 总结

5.1 页表

5.1.1 页表介绍

虽然我们上一篇也简单提过页表,感觉页表也很简单,就是把内存分页之后,在进程中逻辑内存是连续的,存到物理内存中是离散的,所以一个表来记录这个关系。

这个表的结构为:

页号 页框号 保护
0 5 R
1 1 R/W
2 3 R/W
3 6 R

通过逻辑地址的页号,查找到对应物理地址的页框号。

这就是页表的作用。

通常会在系统中设置一个页表寄存器(PTR),存放页表在内存中的起始地址F和页表长度M。进程未执行时,页表的起始地址和页表长度放在进程控制块(PCB)中,当进程被调度时,操作系统内存会把它们存放到页表寄存中。

5.1.2 页表项

是不是觉得页表就这么简单??

通过我需要用一篇文章来介绍就明白,这个页表不简单了,那不简单在哪里???

我们是不是忘记计算页表项的个数了?

按照我们现代操作系统分页的大小一般是4K,然后现在的操作系统内存是4G,(当然目前内存肯定是16G,32G了,不过我们就按课本上的,按4G来计算。)

然后通过计算,一共有多少个页表项:4G/4K = 1M = 1,048,576个。

wakao,1百万个页表项,如果是16G,那就是4百万个页表项。

如果是遍历查找,这需要查到明年(这是夸张的手法,哈哈哈)。

那一个页表项有多大?

页表项的作用就是为了能查到这1百万个页表项,所以只要范围能在1百万以内就可以了。

上面我们计算的页表项个数为:220 = 需要20个二进制位来这么多个内存块号 = 需要3个字节就可以了

为了内存对齐访问,一般会扩展到4个字节,也就是这个页表项 大小为:220 * 4 = 4M字节存储。

每个进程需要4M来存储页表项,如果很多个进程呢??那不得上天了。

正因为页表项很大,不方便查找和储存,所以才需要开始研究页表的结构。

(这里就有人抬杠了,说不是挺方便查找的,用数组的方式,但是用了数组的方式容易查找,就不容易存储啊,又有人说用链表结构来存储,链表结构是容易存储,但是不容易查找,所以我们还是到后面的章节来学习一波,下一节就见分晓)

5.2 页表结构

哈工大老师说的有道理,正因为有多个解的时候,才需要算法,因为页表很大,不要存储和查询,才需要研究一下页表存储的结构,和查询的算法。下面我们就来学习学习。

5.2.1 多级页表

通过上面的分析,我们知道了页表会很大,达到1百万个条目,如果一个条目为4字节,大小达到4M。那如果按照数组的方式储存,我们需要连续开辟4M的大空间,我们前面学习了分页,就是为了把连续大空间给拆小,现在又这样,明显不对。

那我们是不是可以借助分页的思想,进行再分页,没错多级页表就是这种思想。

我们现在就按二级页表来分析一下,虽然linux使用的是三级页表,不过我们先学习二级页表。

我们一个页为4K,4K=212,所以我们页偏移只需要12位即可。

我们从上面分析到4G内存,一个页4K,我们需要220个表。我们现在分为二级页表,也就是第一次为210,第二级也为210

这是我画的一个二级页表,画的比较大,也是因为要符合比例吧。

最左边的是页目录号,也成顶级页表,一共有1024个,每个4byte,刚好是4k,一个页,就是这么凑巧,其实并不是凑巧,就是这么设计的。

二级页表,也是一共有1024个,每个为4byte,存储的是4M的偏移,4M是怎么来的??

因为页大小为4k,个数刚好是1024个,相乘就刚好4M,一个二级页表管理4M,那一共有1024个,管理的就是4G,这就是二级页表的来历。

举个例子,如果我们要找到逻辑地址为0x00403004的物理地址是多少:

我们转换成二进制:01,0000000011,000000000100

对应上面的多级页表:PT1=1,PT2=3,Offset=4。

我们就按上面的图来看吧,PT1=1就相当于我们找到了页号为1的页面,然后继续在这个页面中找到3的位置,上面我没画,就看是3吧。那相当于我们找到的页框号为1027个,计算出地址为:(1024+3)*4k = 4,206,592 然后在加上偏移就等于 4,206,596。

为啥这个逻辑地址跟物理地址一样呢??其实是我们PT1和PT2的索引是一样,所以求出来的结果一样,其实实际上,这两个应该是没有关系的。

如果该页面不在内存中的,页表项中其实中一位表示"在不在内存中"的意思(页表项位还是很多剩余的),如果不在,这个位为0。然后会引发缺页中断。如果在的话,就直接访问物理地址了。

实际上,我们的进程虽然管理内存有4G,但是我们程序是分段的,代码段一般都是在最低(0~4M),数据段会紧跟着代码段(4M-8M),然后就是最顶端的堆栈段了4M,按照这个二级页表,我们这个进程运行的话,主需要4*4K=16K的页表内存就够了,最后一个是页目录表。如果是单级页表就需要4M,这差别很大了。

5.2.2 哈希页表

处理大于32位地址空间的常用方法是使用哈希页表(好像我没见过,哈哈哈),采用虚拟页码作为哈希值(应该一级的页码)。

哈希表的每一个条目都包括一个链表,处理哈希碰撞的。

该算法工作如下:虚拟地址的虚拟页码到哈希表中查找,查找的话,判断是否存在链表,如果有链表就需要一个链表一个链表的查找,看看是否陪匹配虚拟页码,如果匹配就取出响应的页框码,通过这页框码计算出物理地址。

这个就不画图的,就是一个哈希的使用,比较简单。

5.2.3 倒置页表

我们上面学习的多级页表,是从虚拟地址出发,然后采用分级分页,最后才映射到物理地址。如果虚拟地址过大于物理地址,就会导致页表项很多,然后其实映射到物理页还是一样的,所以我们把这种关系进行倒置,这就是倒置页表

倒置页表,是以物理内存为中心,把物理内存进行划分成页,如果一个4G的内存,4K的页,就分为220个页表项,注意:这里是整个系统有220个页表项,不像虚拟内存,有n个进程,就有n*220个页表项。

如果这样存储的话,那虚拟地址怎么映射到物理地址???

这个虚拟地址的定义也跟我们之前不一样了,每个虚拟地址为一个三元组:<进程id, 页码, 偏移>

而每个导致页表的条目为二元组<进程id, 页码>。

当发生内存引用时,由<进程id, 页码>组成的虚拟地址被提交到内存子系统,然后搜索整个倒置页表来寻找匹配,如果匹配,通过这个条目i(因为物理地址是有序),在加上偏移即可得到物理地址。

这个图就是工作的过程,通过条目i*4K+offset来计算物理地址,然后找到对应的内存。

这个倒置页表有啥缺点呢?

很明显嘛,搜索过程就是一个缺点,一遍一遍的搜索全表肯定慢,要想提高这个速度,有两种方法。

第一种:可以使用一个哈希表,就是上面所描述的,直接用哈希表找到了条目i。

第二种:就是后面要介绍的TLB快表。

5.3 快表

因为有多级页表的存在,如果是二级页表,我们访问一次物理地址,需要3次内存访问,第一次访问页目录表,第二次通过页目录表,访问页表,第三次才访问物理地址,按这种访问速度,确实比之前的慢了很多。

5.3.1 局限性原理

看了王道论坛的操作系统,在3.1.8具有快表的地址变换机构一节中,提到了局限性原理。我看着感觉挺不错的。

时间局限性:如果执行了程序中某条指令,那么不久后这条指令很有可能再次执行;如果某个数据被访问过,不久之后该数据很可能再次被访问。(程序中存在大量的循环)

空间局限性:一旦程序访问了某个存储单元,在不久之后,其附近的存储单元也很有可能被访问。(因为很多程序在内存中都是连续存放的)

5.3.2 快表机制

通过上面的局限性分析,我们就想到不用每次都去访问多级页表,而是可以在添加一个小的表,这个表就是转换表缓冲区(Translation Look-aside Buffer, TLB)或快表

现代的TLB查找硬件是指令流水线的一部分,基本上不添加任何性能负担。为了能够在单步的流水线中执行搜索,TLB不应大,通常它的大小在32~1024之间。有些CPU采用分开的指令和数据地址的TLB。

TLB与页表一起使用的方法如下:当CPU产生一个逻辑地址后,它的页码就会发送到TLB。如果TLB中有这个页码的缓存,那就可以直接取出帧码,然后就根据偏移,就可以找到了物理地址。因为TLB是在寄存中,访问速度很快,这样获取几乎没有浪费时间。

如果页码不在TLB中(称为TLB未命中),这时候操作系统一般会出现缺页中断,现在就需要访问页表,通过页码找到对应的帧码,然后在访问物理内存。另外,会将页码和帧码添加到TLB中,这样下次再访问的时候就可以快速找到。页表存储在内存中,需要找到内存的时候,相对会比TLB慢很多,如果是多级页表,速度会更慢。

如果TLB满的话,我们就需要使用淘汰机制,淘汰机制都是相同的,可以使用LRU或者随机替换啥的。

上面画的图就是这样。

5.3.3 访问速率

上面我们也提到访问TLB的速度比访问页表的速度快,那我们现在就来看看加上了快表之后速率怎么算?

我们使用TLB,比较感兴趣的就是TLB的命中率,根据5.3.1的局限性原理上面,我们知道程序运行时,访问的内存页码都是附近的,所以TLB的命中率很高,起码能到达90%。

我们就按90%的命中率来计算,访问TLB的时间为20ns,访问内存的时间为100ns。

按照公式:
有效访问时间=命中率∗(TLB+内存访问时间)+(1−命中率)∗(TLB+2∗内存访问时间)有效访问时间=命中率∗(TLB+内存访问时间)+(1−命中率)∗(2∗内存访问时间)//直接同时访问有效访问时间 = 命中率 * (TLB + 内存访问时间) + (1-命中率)*(TLB + 2*内存访问时间) 有效访问时间 = 命中率 * (TLB + 内存访问时间) + (1-命中率)*(2*内存访问时间) // 直接同时访问 有效访问时间=命中率∗(TLB+内存访问时间)+(1−命中率)∗(TLB+2∗内存访问时间)有效访问时间=命中率∗(TLB+内存访问时间)+(1−命中率)∗(2∗内存访问时间)//直接同时访问
这个公式是快报和页表不能同时查询,如果可以同时查询,后面访问内存的时间可以去掉TLB。

有效访问时间 = 0.9 * 120ns + 0.1 * 220ns = 130ns

如果没有快表,那时间为 2 * 100ns = 200ns。(这个是一级页表的情况)

所以快表的存在也提高了CPU访问物理内存的效率。

5.4 总结

这一篇,介绍了页表和多级页表还有快表,再加上前面的分段,现在操作系统的内存管理已经出来了,下一篇就开始介绍段页结合的实际内存管理了。

内存管理<原理篇>(五、页表和快表)相关推荐

  1. 读懂 JVM 内存管理这篇就够了

    读懂 JVM 内存管理这篇就够了 JVM 的内存结构 程序计数器 作用 概述 PC寄存器的常见问题 虚拟机栈 栈中可能出现的异常 栈的存储单位 栈运行原理 栈帧的内部结构 局部变量表 槽 Slot 操 ...

  2. 从内存管理原理,窥探OS内存管理机制

    摘要:本文将从最简单的内存管理原理说起,带大家一起窥探OS的内存管理机制,由此熟悉底层的内存管理机制,写出高效的应用程序. 本文分享自华为云社区<探索OS的内存管理原理>,作者:元闰子 . ...

  3. Linux内存管理宏观篇(七)虚拟内存

    Linux内存管理宏观篇(七)虚拟内存 前面知道了物理内存,物理内存是实打实的,我只有这么多,用的时候你只能用这么多. 为了解决一些问题,产生虚拟内存,通过虚拟内存可以让我们每个进程都能拥有虚拟的3G ...

  4. Linux内存管理原理笔记

    一.内存管理 1. 每个进程应该有自己的内存空间.内存空间都是独立的.相互隔离的.对于每个进程来讲,看起来应该都是独占的.进程不能直接访问物理内存地址,因为假如三个程序同时访问或写入同一个物理内存地址 ...

  5. 一文搞懂Linux 内存管理原理

    导语 linux 内存是后台开发人员,需要深入了解的计算机资源.合理的使用内存,有助于提升机器的性能和稳定性.本文主要介绍 linux 内存组织结构和页面布局,内存碎片产生原因和优化算法,linux ...

  6. Linux内存管理原理【转】

    转自:http://www.cnblogs.com/zhaoyl/p/3695517.html 本文以32位机器为准,串讲一些内存管理的知识点. 1. 虚拟地址.物理地址.逻辑地址.线性地址 虚拟地址 ...

  7. Linux内存管理原理

    本文以32位机器为准,串讲一些内存管理的知识点. 1. 虚拟地址.物理地址.逻辑地址.线性地址 虚拟地址又叫线性地址.linux没有采用分段机制,所以逻辑地址和虚拟地址(线性地址)(在用户态,内核态逻 ...

  8. linux内存管理(十)-页表管理

    页表管理方法 之前也讲过页表的结构,现在更加详细的讲解一下,页表最主要的作用就是将虚拟地址转化为物理地址,其实他还有两个作用,一个是管理cpu对物理页的访问权限(读写执行权限),另一个是隔离各个进程的 ...

  9. 行动力决定了一个人的成败,有想法,就去做! C#的内存管理原理解析+标准Dispose模式的实现

    尽管.NET运行库负责处理大部分内存管理工作,但C#程序员仍然必须理解内存管理的工作原理,了解如何高效地处理非托管的资源,才能在非常注重性能的系统中高效地处理内存. C#编程的一个优点就是程序员不必担 ...

最新文章

  1. wsl for pycharm vscode
  2. 你必须知道的10个提高Canvas性能技巧
  3. PHP一行命令打印当前系统时间
  4. Java 内部类示例
  5. element-ui使用导航栏跳转路由用法
  6. java string问题_Java关于String的问题?
  7. 但我发现了幸福的超级玛丽
  8. 关于controller的总结 2021-04-22
  9. const型指针区别 const * 和* const
  10. ACM程序设计竞赛开幕式致辞
  11. 兄弟,学点AI吗?2知识的确定性系统
  12. fft算法的c语言实现,快速傅立叶变换(FFT)算法(蝶形算法)的C/C++源代码(zz)
  13. 悟空CRM客户关系管理系统测试
  14. (软考)系统分析师——标准化知识
  15. antdesign 新增页面_ant design pro 新增页面
  16. python 广告联盟_谷歌广告月入10000美金的一些经验谈
  17. onblur 与onclick 冲突;onblur导致onclick事件丢失
  18. python数据清洗工具、方法、过程整理归纳(七、数据清洗之数据预处理(二)——异常值处理、数据离散化处理)
  19. 杨焘鸣:沟通态度比技巧重要
  20. TSF微服务治理实战系列(四)——服务安全

热门文章

  1. Android 渐变背景色
  2. 实验6 单个交换机虚拟局域网
  3. 记录自己第一个Kaggle银牌
  4. 创建 deployment 每个组件如何响应?
  5. 奥特曼打小怪兽,赢了的和boss打
  6. sqlserver 死锁,事务(进程 ID)与另一个进程被死锁在锁资源上,并且已被选作死锁牺牲品。请重新运行该事务
  7. 融云 IM +RTC 优惠上线~15 天免费体验,1 年服务买一赠一
  8. Javascript核心DOM操作 学习笔记
  9. 给 Web 前端开发人员推荐20款 CSS 编辑器
  10. 做好这几点,web应用性能将极大提高(二)