虚拟内存

参考学习:《computer architecture》课程

没有虚拟内存面临的问题

1. 没有足够内存

程序是可以访问到32bit的4G内存的任意位置的,但是如果物理内存没有4GB,比如只有1GB(事实上,即便有4GB内存,由于内核会占用一定内存,所以留给用户的内存也没有4GB,可能只有2GB可以给用户进程用);所以这就导致访问超过1GB内存的时候,直接Crash

2. 内存空洞(内存碎片问题)

进程是需要连续的内存空间的,即便整体可用内存足够,但是由于是都是空洞,不连续,这样也没法让进程跑起来

3. 进程隔离和安全问题

不同的进程会访问同一个内存地址,这回导致进程相互影响,直接crash;显然进程如果没能隔离,可靠性和安全性基本无法保证

虚拟内存如何解决上面的问题

解决问题1

illusion: n.错误的观念; 幻想; 幻想的事物; 错觉;

利用磁盘交换,内存不断的交换使用,给进程造成无限内存的错觉

解决问题2

虚拟内存是映射到物理内存的,所以利用map可以映射到任意的物理内存,内存空洞/碎片问题将不再成为问题

解决问题3

虚拟内存map映射可以完美的解决程序的隔离性问题,如果映射到相同物理地址,则可以任务是进程共享的内容,否则可以映射到不同的物理内存,确保某个进程不会影响其它进程的数据

Page Fault

  • VA:Virtual Address 虚拟地址
  • PA:Physical Address 物理地址
  • MMU:Memory Manage Unit 内存管理单元
  • TLB:Translation Lookaside Buffer 旁路快表缓存/地址变换高速缓存
  • PTE:Page Table Entry 分页表项

  • CPU MMU

VA到PA的转换流程

  1. 当CPU给MMU传新虚拟地址之后,MMU先去问TLB那边有没有,如果有就直接拿到物理地址发到总线给内存,开始工作
  2. TLB容量比较小,难免发生Cache Miss,这时候MMU还有保底的老武器页表 Page Table,在页表中找到之后MMU除了把地址发到总线传给内存,还把这条映射关系给到TLB,让它记录一下刷新缓存
  3. TLB容量不满的时候就直接把新记录存储了,当满了的时候就开启了淘汰大法把旧记录清除掉,来保存新记录
  4. 如果CPU给MMU的虚拟地址在TLB和Page Table都没有找到对应的物理页帧或者权限不对,该怎么办呢?即有:page fault

  • Page Fault:假如目标内存页在物理内存中没有对应的页帧或者存在但无对应权限,CPU 就无法获取数据,这种情况下CPU就会报告一个缺页错误;这是一个由硬件中断触发的可以由软件逻辑纠正的错误

page fault类型

  • Hard Page Fault 也被称为Major Page Fault,翻译为硬缺页错误/主要缺页错误,这时物理内存中没有对应的页帧,需要CPU打开磁盘设备读取到物理内存中,再让MMU建立VA和PA的映射。
  • Soft Page Fault 也被称为Minor Page Fault,翻译为软缺页错误/次要缺页错误,这时物理内存中是存在对应页帧的,只不过可能是其它进程调入的,发出缺页异常的进程不知道而已,此时MMU只需要建立映射即可,无需从磁盘读取写入内存,一般出现在多进程共享内存区域。
  • Invalid Page Fault 翻译为无效缺页错误,比如进程访问的内存地址越界访问,又比如对空指针解引用内核就会报segment fault错误中断进程直接挂掉。

导致Page Fault的一些场景

  • 非法操作访问越界 这种情况产生的影响也是最大的,也是Coredump的重要来源,比如空指针解引用或者权限问题等都会出现缺页错误。
  • 使用malloc新申请内存 malloc机制是延时分配内存,当使用malloc申请内存时并未真实分配物理内存,等到真正开始使用malloc申请的物理内存时发现没有才会启动申请,期间就会出现Page Fault。
  • 访问数据被swap换出 物理内存是有限资源,当运行很多进程时并不是每个进程都活跃,对此OS会启动内存页面置换将长时间未使用的物理内存页帧放到swap分区来腾空资源给其他进程,当存在于swap分区的页面被访问时就会触发Page Fault从而再置换回物理内存。

页面置换算法

当主存空间已满而又需要装入新页时(或者有缺页中断发生时),页式虚拟存储管理必须按照一定的算法把已在主存的一些页调出去。选择淘汰页的工作称为页面调度,选择淘汰页的算法称为页面调度算法,页面调度算法设计不当,会出现刚被淘汰的页面立即又要调入,并如此反复,这种现象称为抖动或颠簸。

  • 最佳页面替换算法(OPT):理想的调度算法,只可模拟,不可实现。当要调入新页面时,首先淘汰以后不再访问的页,然后选择距现在最长时间后再访问的页。

  • 先进先出页面调度算法(FIFO):总是淘汰最先调入主存的那一页,或者说主存驻留时间最长的那一页(常驻的除外)。模拟的是程序执行的顺序性,有一定合理性。会出现Belady现象(如果对—个进程未分配它所要求的全部页面,有时就会出现分配的页面数增多但缺页率反而提高)

  • 最近最少用页面调度算法(LRU):淘汰最近一段时间内最久未被访问的那一页,认为那些刚被使用过的页面可能还要立即被使用,而那些在较长时间内未被使用的页面可能不会立即使用。模拟了程序执行的局部属性,既考虑了循环性又兼顾了顺序性,但严格实现的代价大(需要维持特殊队列),模拟实现的方法为: 1.最近未使用页面替换算法(NRU)/引用位法:每页建一个引用位,供硬件使用;设置一个时间间隔中断,周期性地把所有页的引用位置0;地址转换时,页引用标志置1;淘汰页面时,从页引用标志为0的页中间随机选择。该方法开销小但时间间隔多长是个难点。

    1. 最不经常使用页面替换算法(NFU)/计数法:基于时间间隔中断,并给每一页设置一个页引用计数器;时间间隔中断发生后,所有计数器置0;每访问页1次就给计数器加1;淘汰页面时,选择计数值最小的页面淘汰。
    2. 计时法:基于时间间隔中断,为每页增设一个计时单元;每当页面被引用时把当前绝对时间置入计时单元;时间间隔中断发生后,所有计时单元全部清除;淘汰页面时,选择绝对时间最小的页面淘汰。
    3. 老化算法:基于时间间隔中断,为每个页设置一个多位寄存器;每当页面被访问时,寄存器最左边位置0;时间间隔中断发生后,所有寄存器右移一位;淘汰页面时,选择值最小的寄存器对应的页面淘汰。
  • LFU(Least Frequently Used)

  • 第二次机会页面调度算法(SCR):淘汰最先进入内存的页面如果最近还在使用,仍然有机会像新调入页面一样留在内存中。页面调入主存时,其引用标志位置1;访问主存页面时,其引用标志位置1;淘汰页面时,从FIFO页面队列对首开始扫描,把所遇到的引用标志位是1的页面的引用标志位清0,并移至队尾(看作新调入的页再给一次机会),把所遇到的引用标志位是0的页面淘汰(其最早进入内存且最久未被使用)。

  • 时钟页面替换算法(Clock):采用循环队列机制构造页面队列,形成了一个类似于钟表面的环形表。队列指针则相当于钟表面上的表针,指向可能要淘汰的页面。使用页引用标志位。页面调入主存时,其引用标志位置1;访问主存页面时,其引用标志位置1;淘汰页面时,从指针当前指向的页面开始扫描循环队列,把所遇到的引用标志位是1的页面的引用标志位清0,并跳过,把所遇到的引用标志位是0的页面淘汰,指针推进一步。

颠簸或抖动(thrashing)

thrash:v.(作为惩罚用棍子等) 抽打,连续击打; (使) 激烈扭动,翻来覆去; 彻底击败,重创(对手); n.快节奏重金属摇滚乐; 载歌载舞的聚会;

在更换页面时,如果更换页面是一个很快会被再次访问的页面,则再次缺页中断后又很快会发生新的缺页中断。整个系统的效率急剧下降,这种现象称为颠簸(抖动);颠簸本质上是指频繁的页调度行为

内存颠簸的解决策略:

  1. 如果是因为页面替换策略失误,可以修改替换算法来解决这个问题;
  2. 如果是因为运行的程序太多,造成程序无法同时将所有频繁访问的页面调入内存,则要降低多道程序的数量。
  3. 否则,还剩下两个办法:1.终止该进程;2.增加物理内存容量;
Copyright @doctording all right reserved,powered by Gitbookupdate at: 2020-12-22 12:57:52

results matching ""

    No results matching ""