今天重点噢!!!
分段机制
分段机制:以段的形式管理/分配物理内存。应用程序的虚拟地址空间被分为大小不等的段,段是有实际意义的,每个段定义了一组逻辑信息。,例如有主程序段 MAIN、子程序段X、数据段D 及 栈段S等。
段表:分段管理通过段表映射虚拟地址和物理地址。
虚拟地址的组成:
- 段号:标识着该虚拟地址属于整个虚拟地址空间中的哪一个段
- 段内偏移量:相对于该段起始地址的偏移量
具体的地址翻译过程:
- MMU 首先解析得到虚拟地址中的段号
- 通过短号去该应用程序的段表中找到对应的段表项取出对应的段信息
- 从段信息中取出该段的起始地址(物理地址)加上虚拟地址中的段内偏移量得到最终的物理地址
注意:段表项可能并不存在,段表项被删除(软件错误、软件恶意行为等情况),段表项还未创建(如果系统内存不足或者无法分配到连续的物理内存块就会导致段表项无法被创建)
分段机制为什么会导致内存外部碎片
段与段之间留下碎片空间,这个空间不足以映射给虚拟地址空间中的段。
举个栗子:
假设可用物理内存为 5G 的系统使用分段机制分配内存。
这 5G 的物理内存分成四个进程:
- 进程1:0~1G 第一段
- 进程2:1~3G 第二段
- 进程3:3~4.5G 第三段
- 进程4:4.5~5G 第四段
若此时,关闭了进程1和进程4,那么第一段和第四段的内存会释放,这时空闲的1.5G物理内存不是连续的,导致没办法将空闲的物理内存分配给一个需要1.5G 物理内存的进程。此时就造成了内存外部碎片。
分页机制(广泛使用)
分页机制:分页机制把主存分为连续等长的物理页,应用程序的虚拟地址空间也被分为连续等长的虚拟页。
注意:这里的页是等长的
物理内存资源的离散分配:在分页机制下,一个用程序虚拟地址空间中的任意虚拟页可以被映射到物理内存中的任意物理页上,这实现了物理内存资源的离散分配。
避免外部内存碎片:分页机制按照固定页大小分配物理内存,是的物理内存资源易于管理,可有效避免分段机制中外部内存碎片的问题。
页表:分页管理通过页表映射虚拟地址和物理地址。
在分页机制下,每个应用程序都会有一个对应的页表
分页机制下的虚拟机由页号和页内偏移量组成
- 页号:通过虚拟页号可以从页表中取出对应的物理页号
- 页内偏移量:物理页起始地址+页内偏移量=物理内存地址
地址翻译过程:
1、MMU 首先解析得到虚拟地址中的虚拟页号
2、通过虚拟页号去该应用程序的页表中取出对应的物理页号(找到对应的页表项)
3、用该物理页号对应的物理页起始地址(物理地址)加上虚拟地址中的页内偏移量得到最终的物理地址
注意:
- 页表中还存有注入访问标志、脏数据标识位等信息。
- 通过虚拟页号不一定会找到对应的物理页号;找到了物理页号也不一定得到最终得物理地址后对应的物理页。因为可能会存在页缺失
一般实际应用中都是多级页表
原因:应用程序运行起来页表开销比较大,但是28原则,绝代部分应用程序中只能用到页表中的几项,所以使用多级页表。一般 32 位系统为二级页表,64位系统为四级页表。
多级页表属于时间换空间的典型场景,利用增加页表查询的次数减少页表占用的空间。
TLB 转址旁路缓存/快表
为了提高虚拟地址到物理地址的转换速度,操作系统在页表方案基础之上引入了转址旁路缓存。
在主流的X86-64体系结构下,TLB属于内存管理单元MMU内部的单元,本质上就是一块高速缓存,缓存了虚拟页号到物理页号的映射关系。我们可以简单将其看作是存储着键(虚拟页号) 值(物理页号) 对的哈希表
使用 TLB 之后的地址翻译流程:
- 用虚拟地址中的虚拟页号作为 key 去 TLB 中查询
- TLB 命中 TLB hit:如果能查到对应的物理页的话,就不用再查询页表。
- TLB 未命中:如果不能查到对应的物理页的话,还是要去查询主存中的页表,同时将页表中的该映射表项添加到 TLB 中。
- 当 TLB 填满后,又要登记新页时,就按照一定的淘汰策略淘汰掉快表中的一个页。
换页机制
换页机制:当物理内存不够用的时候,操作系统选择将一些物理页的内容放到磁盘上去,等要用到的时候再将它们读取到物理内存中。也就是说,换页机制利用磁盘这种较低廉的存储设备扩展的物理内存。
所以说,OS 所有进程运行所需的物理内存即使比真实物理内存大也可以运行但速度会变慢的原因在此。
页缺失
又名硬错误、分页错误、寻页缺失、页故障等
当软件试图访问已映射在虚拟地址空间中,但是目前并未被加载在物理内存中的一个分页时,由 MMU 所发出的中断。
- 硬性页缺失:物理内存中没有对应的物理页。
- 软性页缺失:物理内存中有对应的物理页,但虚拟页还未和物理页建立映射。
常见的页面置换算法
- 最佳页面置换算法OPT:优先淘汰的页面是以后永不使用的,或者是在最长时间内不再被访问的页面。
- 先进先出页面置换算法FIFO:淘汰最先进入内存的页面。队列实现。
- 最近最久未使用页面置换算法 LRU:LRU 算法赋予每个页面一个访问字段记录一个页面自上次被访问依赖所经历的时间T,淘汰T值最大的。
- 最少使用页面置换算法LFU:淘汰之前一段时间内使用最少的页面作为淘汰页。
- 时钟页面置换算法:最近未使用算法。
FIFO 性能缺陷
- 经常访问或者需要长期存在的页面会被频繁调入调出
- 存在 Belady 现象:被置换的页面并不是进程不会访问的,有时就会出现分配的页面数增多单缺页率反而提高的异常现象。原因:FIFO 算法只考虑了页面进入内存的顺序,并没有考虑页面访问的频率和紧迫性。
分页机制和分段机制
共同点
- 都是非连续内存管理的方式
- 都采用了地址映射的方法,将虚拟地址映射到物理地址,以实现对内存的管理和保护。
区别
-
分页机制以页面为单位进行内存管理,分段机制以段为单位进行内存管理。
页的大小是固定的,由OS决定,通常为2的幂次方;段的大小不固定,取决于当前程序。
-
页时物理单位,段是逻辑单位
-
分段会出现外部内存碎片;分页解决了外部内存碎片但任然会出现内部内存碎片。
-
分页机制对程序没有任何要求,程序只需要按照虚拟地址进行访问即可;分段机制需要程序员将程序分为多个段,并且显示地使用段寄存器来访问不同的段。
段页机制
结合了段式管理和页式管理:把物理内存先划分为若干段,每个段又继续分成若干个大小相等的页。
地址翻译过程:
- 段式地址映射
- 页式地址映射
局部性原理
局部性原理是指再程序执行过程中,数据和指令的访问存在一定空间和时间上的局部性特点。其中,时间局部性是指一个数据项或指令在一段时间内被反复使用的特点,空间局部性是指一个数据项或指令在一段时间内与其相邻的数据项或指令被反复使用的特点。
页表将虚拟地址转化为物理地址,从而完成内存访问过程中局部性原理作用:
- 时间局部性:由于程序中存在一定的循环或者重复操作,因此会反复访问同一个页或一些特定的页。分页机制利用时间局部性,采用缓存机制来提高页面的命中率:将最近访问过的一些页放入缓存中,下一次访问的页在缓存中直接从缓存中读取就不需要再次访问内存。
- 空间局部性:由于程序中数据和指令的访问通常具有一定的空间连续性,当访问某个页,往往会顺带访问其相邻的一些页。分页技术利用空间局部性,采用预取技术将相邻的一些页读入内存缓存中,便于在未来访问时能够之间使用。
期待一下明天的内容吧V