zoukankan      html  css  js  c++  java
  • 《操作系统》课程笔记(Ch09-虚拟内存)

    之前讨论的内存管理策略都将多个进程保存在内存中,实现多道程序。本节介绍虚拟内存技术,使得进程不必完全处于内存,而可以通过与后备存储器进行换入换出等技术,使用大于物理内存的内存空间。

    请求调页

    仅在需要时才(从后备存储器)加载页面(到内存)。

    当进程试图访问尚未调入内存中的页面时,发生缺页错误。缺页错误的中断发生在指令执行过程中。当处理结束后,重新启动被陷阱中断的指令(即当前指令)。

    缺页情形下的有效访问时间:EAT=p*缺页情况时间+(1-p)*内存访问时间,p为缺页率。

    对于请求调页,降低缺页率很重要,否则会增加有效访问时间。

    写时复制 Copy on Write

    父进程和子进程最初共享相同的页面来工作。如果某个进程需要写入共享页面,那么就创建共享页面的副本用来修改。

    页面置换

    当没有空闲帧时,牺牲一个帧,用于调入新的帧。

    我们希望页面置换能有最小缺页错误率。页面置换有许多种算法:

    • FIFO先进先出:优先换掉最老的帧

      • 问题:Belady异常

        按道理来说,可用帧数越多,缺页错误越少。但对于某些引用串,帧数多的,缺页率反而高。

    • OPT最优:离线算法,假设能看到以后的所有访问目标

      向未来看,换掉最远才被使用的帧(找不到就是无穷远)

    • LRU最近最少使用:回头看,总结过去

      向过去看,换掉目前用的最少的帧,如果有等同的,则换掉更老的

    LRU算法近似化

    真正的LRU很难被硬件支持。通常使用一些近似的方法:

    • 引用位

      使用1位标记位,最初为0,用了就为1,替换时换0的(即没用的)

      缺点是不能知道具体先后顺序

    • 第二次机会

      维护一个“下个牺牲”指针。引用位为0就替换;为1则给第二次机会,引用位置0,指针下移。

      这样,这一位只有在再次被指针指到时才会牺牲

    • 增强型第二次机会

      使用两个bit,细分情况

    帧分配

    解决在各个进程间如何分配固定数量的可用内存的问题。

    • 平均分配
    • 比例分配

    系统抖动

    抖动指的是高度页面调度活动,造成的原因是进程获得的页面帧数不足以支持它的活动,使得它需要频繁进行页面调换。

    抖动说明多道程序程度过高,此时的表现是CPU利用率很低,而磁盘高度活动。解决方法是适当降低多道程序程度。

    防止抖动

    工作集模型

    为了防止抖动,应为进程提供足够多的帧,但也不能过多。如何知道进程需要多少帧?可以使用工作集模型进行近似。

    工作集是最近Δ个引用(往前看Δ项)组成的页面集合。WSSi表示进程Pi的工作集长度,D=ΣWSSi就是帧的总需求量,如果D大于帧的总量,则会发生抖动。

    工作集模型利用的是程序的局部性原理。Δ不能太大,否则会包含程序的多个局部;也不能太小,否则无法包含整个局部。

    缺页错误频率

    根据进程发生缺页错误的频率与上下阈值的关系,动态地为它增加或减少帧数。

    内核内存

    为内核分配内存不同于为普通用户模式进程分配,主要有两个不同点:

    • 内核使用的数据结构大小不同,有的小于一页,因此内核要保守地使用内存,并减少碎片浪费
    • 一些硬件设备与物理内存直接交互,无法使用虚拟内存技术,必须常驻在连续的物理内存中

    伙伴系统 Buddy System

    对物理连续的页面按照2的幂进行分割与分配(每个段落分为两个伙伴),当内存交还时,可以快速合并小块为大块。

    缺点是,由于圆整到下一个2的幂,很可能造成分配段落中的内碎片

    Slab

    每个对象存放在各自的cache中,cache映射到slab,slab是在内存上物理连续的页面。每个cache由一个或多个slab组成,slab按照对象的大小来分块。

    slab分配器的优点:

    • 没有碎片引起的内存浪费
    • 可以快速满足内存请求

    其他

    预调页面

    纯请求调页在进程启动时会发生大量缺页错误(因为新的程序找不到任何一个页面),在作为换出进程重新启动时也可能出现类似现象。

    预调页面的思想是提前调进所需的页面。在进程换出时,可以保存它当前的工作集,从而在被重启时提前调入相关页面。

    有时,预调页面成本不一定小于直接处理缺页错误的成本(比如预调的命中率太低)。

    页面大小

    页面大小通常是2的幂。

    • 小的页面大小会造成页表过大
    • 较小的页面可以更好地利用内存
    • 最小化IO时间期望较大的页面大小(避免频繁地IO,尽管传输量大,但传输次数少)
    • 较小的页面却有可能减少总的IO次数,因为可能更好地精确匹配了程序的局部性
    • ……

    TLB范围

    一个指标TLB范围(TLB Reach)=TLB条数 × 页面大小表示了通过TLB能访问的内存量,该值越大越好。

    • 增加TLB的条目数可以提高命中率,但是TLB的成本很高(关联内存)
    • 增加页面大小可能造成碎片增加。有的系统采用不同大小的页面,此时需要操作系统而非硬件管理TLB

    程序结构

    仔细选择数据结构和编程结构可以增加局部性,降低缺页错误率和工作集页面数

  • 相关阅读:
    python 3 dict函数 神奇的参数规则
    python 3 黑色魔法元类初探
    私有变量为何传给了子类?
    [转]django-registration quickstart
    DoesNotExist at /account/
    DoesNotExist at /admin/
    setting.py
    Python excel 奇怪的通信规则
    Python 一个奇特的引用设定
    Chrome 内存和CPU消耗量双料冠军
  • 原文地址:https://www.cnblogs.com/zxuuu/p/12969233.html
Copyright © 2011-2022 走看看