zoukankan      html  css  js  c++  java
  • 第 8 章 内存管理策略

      为了实现性能改进,应将多个进程保存在内存中,也就是说必须共享内存。

    8.1 背景

      内存是现代计算机运行的核心。内存由一个很大的字节数组来组成,每个字节都有各自的地址。

    8.1.1 基础硬件

      CPU可以直接访问的通用存储只有内存和处理器内置的寄存器。

      每个进程都有一个独立的内存空间,可以保护进程不会互相影响。

    • 基地址寄存器(base register):最小的合法的物理内存地址。
    • 界限地址寄存器(limit register):指定了范围的大小。

      合法范围为(base, base + limit)register

      内存空间保护的实现是通过CPU硬件对在用户模式下产生的地址与寄存器的地址进行比较来完成的。

      只有操作系统可以通过特殊的特权指令,才能加载基地址寄存器和界限地址寄存器。不允许用户程序修改它们。

    8.1.2 地址绑定

      源程序中的地址通常是用符号表示的,编译器通常将这些符号地址绑定到可重定位的地址。链接程序或加载程序再将这些可重定位的地址绑定到绝对地址。每次绑定都是从一个地址空间到另一个地址空间的映射。

      通常,指令和数据绑定到存储器地址可在沿途任何一步中进行:

    • 编译时
    • 加载时
    • 执行时

    8.1.3 逻辑地址空间和物理地址空间

      CPU生成的地址通常称为逻辑地址,而内存单元看到的地址(即加载到内存地址寄存器)通常称为物理地址。

      编译时和加载时的地址绑定方法生成相同的逻辑地址和物理地址。

      由程序生成的所有逻辑地址的集合称为逻辑地址空间,这些逻辑地址对应的所有物理地址的集合称为物理地址空间。

      执行时地址绑定,逻辑地址空间和物理地址空间是不同的。

      从虚拟地址到物理地址的运行时的映射是有内存管理单元(Memory-Management Unit,MMU)的硬件设备完成的。基地址寄存器在这里被称为重定位寄存器。用户进程所生产的地址在送交内存之前,都将加上重定位寄存器的值。

      用户程序不会看到真实的物理地址。

    8.1.4 动态加载

      一个程序只有在被调用时才会加载。所有程序都以重定位加载格式保存到磁盘上。

    8.2 交换

      进程必须在内存中以便执行。不过,进程可以暂时从内存中交换到备份存储,当再次执行时再调回到内存。

      交换有可能让所有进程的总的物理地址空间超过真实系统的物理地址就,从而增加了系统的多道程序程度。

    8.3 连续内存分配

      早期方法,每个进程位于一个连续的内存区域,与包含下一个进程的内存相连。

    8.3.1 内存保护

      重定位寄存器+限界寄存器

    8.3.2 内存分配

      最简单的方法就是将内存分成多个固定大小的分区,每个分区只包含一个进程。因此,多道程序的程度受限于分区数。

      可变分区方案:操作系统有一个表,用于记录哪些内存可用和哪些内存已用。开始,所有内存都可用于用户进程,因此可用作为一个大块的可用内存,称为孔。

      动态存储分配问题,从一组可用孔中选择一个空闲孔的最常用的方法包括:

    • 首次适应,分配首个足够大的孔。
    • 最优适应,分配最小的足够大的孔。
    • 最差适应,分配最大的孔。

    8.3.3 碎片

      外部碎片,分区之间。解决方法之一是紧缩,移动内存内容,将所有空闲空间合并成一块。另一种方法是运行进程的逻辑地址空间是不连续的。

      内部碎片,分区内部,分区大于进程的大小。

    8.4 分段

       允许进程的物理地址空间是非连续的。

    基本方法

      逻辑地址空间由一组段构成,每个段都有 <段号, 段偏移>。

    分段硬件

      实际物理地址是一维的,所以要将逻辑地址二维映射到一维上。用段表实现。

      段表的每个条目都由段基地址和段界限组成。段基地址包含该段在内存中开始的物理地址,段界限指定了该段的长度。

      

      逻辑地址 <段号 s, 段偏移 d>, 段号用作段表的索引,段偏移d位于[ 0 , 段界限] 之间。

      实际物理地址 = 段号 s ---> 基地址 + 段偏移 d

    8.5 分页

      分页也是物理地址不联系,分页避免了外部碎片和紧缩,分段不可以。也避免了将不同大小的内存块匹配到交换空间的麻烦。

    基本方法

      将物理内存分为固定大小的块,称为帧或页帧(frame)。

      将逻辑内存也分为同样大小的块,称为页或页面(page)。

      CPU生成的地址分为 <页码p, 页偏移d>,页码作为页表的索引,页表包含每页所在物理内存的基地址。

      页大小(与帧大小一样)是由硬件来决定的,页的大小为 2 的幂。

      如果逻辑地址空间为2m,且页是大小为2n字节,那么逻辑地址的高 m-n 位表示页码,而第 n 位表示页偏移。如下:

         页码  页偏移  

        <    p      ,     d    >

         m-n          n

      

      物理地址 = 页码---> 基地址 x 帧长度(字节) + 页偏移 

      分页本身是一种动态的重定位。采用分页方案有内部碎片。分页增加了上下文切换的时间。

    硬件支持

      页表的硬件实现,标准的解决方法是采用专用的、小的、查找快速的高速硬件缓冲,称为转换表缓冲区(Translation Look-aside Buffer,TLB)。

      TLB是关联的高速内存。TLB条目由两部分组成:键(标签)和值。

      TLB与页表的使用方法如下:TLB只包含少数页表条目,当CPU产生一个逻辑地址后,它的页码就发送到TLB,如果找到这个页码,它的帧码就立即可用,否则即TLB未命中,就需要访问页表。

    保护

      分页环境下的内存保护是通过与每个帧关联的保护位来实现的,这些位保存在页表中。

      用一个位来定义一个页是可读写或只读,还有一个位:有效-无效位,有效时表示相关的页在进程的逻辑地址空间内,是合法的页。操作系统可通过对该为的设置,可以允许或禁止对某页的访问。

    共享页

      分页的优点之一是可以共享公共代码。

      可重入代码是不能自我修改的代码,它在执行期间不会改变。

    8.6 页表结构

      最常用的组织页表的技术:分层分页、哈希页表和倒置页表

    8.6.1 分层分页

      将页表再分页。

      

  • 相关阅读:
    微信JS SDK Demo
    微信JS SDK使用权限签名算法
    微信JS接口
    微信分享JS接口失效说明及解决方案
    微信支付开发(2) 扫码支付模式一
    不懂技术的人不要对懂技术的人说这很容易实现
    独立开发者经验分享
    微信公开课PRO版张小龙演讲全文
    RC4加密算法的原理及实现
    上传APP加入视频预览--精简点名
  • 原文地址:https://www.cnblogs.com/astonc/p/12154502.html
Copyright © 2011-2022 走看看