• 三、内存管理 (一)内存管理基础


    目录

    1.1程序运行的基本过程

    1.1.1 编辑、编译、链接、装入

    1.1.2链接的三种方式

    1.1.3装入的三种方式

    1.2内存管理基本概念 

    1.2.1内存保护

     1.2.2内存空间扩充

     1.2.3地址转换功能

    1.2.4内存空间的分配与回收

    1.2.4.1连续分配管理方式

    1.2.4.1.1单一连续分配

    1.2.4.1.2固定分区分配

    1.2.4.1.3动态分区分配

    1.2.4.2基本分页存储管理

    1.2.4.2.1基本地址变换机构

    1.2.4.2.2具有快表的地址变换机构 

    1.2.4.2.3二级页表

    1.2.4.3基本分段存储管理

    1.2.4.3.1基本地址变换机构

    1.2.4.3.2段的共享与保护 

    1.2.4.4段页式管理 ​

    1.2.4.4.1基本地址变换机构 

    1.2.4.5三种离散分配方式对比


    1.1程序运行的基本过程

    1.1.1 编辑、编译、链接、装入

    • 形成完整逻辑地址的阶段是链接。 形成物理地址的阶段是装入
    • 逻辑地址又称相对地址,物理地址又称绝对地址

    1.1.2链接的三种方式

    • 静态链接装入前链接成一个完整装入模块以后不再拆开。
    • 装入时动态链接:运行前边装入边链接,便于修改和实现对目标模块的共享。
    • 运行时动态链接边运行边链接,加快程序的装入过程,还可节省大量内存空间。

    1.1.3装入的三种方式

    • 绝对装入只适合于单道程序环境。编译程序将产生绝对地址(物理地址)的目标代码。装入程序按照装入模块中的地址,将程序和数据装入内存。
    • 静态重定位(可重定位装入)在多道程序环境下,根据内存的当前情况,将装入模块装入内存的适当位置。在装入时对目标程序中指令和数据地址的修改过程称为重定位,其地址变换通常是在进程装入时一次完成的,故称为静态重定位
    • 动态重定位(动态运行时装入):装入内存后所有的地址仍然是逻辑地址,把地址转换推迟到程序真正要执行时才进行。这种方式需要一个重定位寄存器的支持。允许程序在内存中移动。

    1.2内存管理基本概念 

    1.2.1内存保护

    • 设置一对上、下限寄存器,存放进程的上、下限地址。进程的指令要访问某个地址时,CPU检查是否越界。
    • 采用重定位寄存器(又称基址寄存器)和界地址寄存器(又称限长寄存器)进行越界检查。重定位寄存器中存放的是进程的起始物理地址。界地址寄存器中存放的是进程的最大逻辑地址

    系统中只需设置一个重定位寄存器,只需在切换程序执行时重置寄存器内容。 

     1.2.2内存空间扩充

    这里覆盖与交换大纲已删,虚拟存储技术是为了解决主存-辅存层关于存储容量的问题而提出的,将在下一小节重点学习。

     1.2.3地址转换功能

    • 绝对装入 ,单道程序阶段,无操作系统
    • 静态重定位,早期多道批处理阶段。
    • 动态重定位,现代操作系统。

    1.2.4内存空间的分配与回收

    为了能够将用户程序装入内存,必须为它分配一定大小的内存空间。这就引出了存储管理方式。

    存储管理方式随着操作系统的发展而发展。在操作系统由单道向多道发展时,存储管理方式便由单一连续分配发展为固定分区分配。为了能更好地适应不同大小的程序要求,又从固定分区分配发展为动态分区分配

    为了更好地提高内存的利用率,进而从以上的连续分配方式发展到以下的离散分配方式——页式存储管理。为了满足用户在编程和使用方面的要求,又引入了分段存储管理。而段页式存储管理集中了分页管理和分段管理的优点。

    1.2.4.1连续分配管理方式

    1.2.4.1.1单一连续分配

    内存被分为系统区用户区。系统区通常位于内存的低地址部分,用于存放操作系统相关数据;用户区用于存放用户进程相关数据。内存中只能有一道用户程序,用户程序独占整个用户区空间。

    优点:无外部碎片;可以采用覆盖技术扩充内存;不一定需要采取内存保护

    缺点:只能用于单用户、单任务的操作系统中有内部碎片存储器利用率极低

    1.2.4.1.2固定分区分配

    •  无外部碎片,会产生内部碎片。

    1.2.4.1.3动态分区分配

    又称可变分区分配。这种分配方式不会预先划分内存分区,而是在进程装入内存时,根据进程的大小动态地建立分区,并使分区的大小正好适合进程的需要。因此系统分区的大小和数目是可变的。 

     

     

    1.2.4.2基本分页存储管理

    引入页面和页框 

    分页管理不会产生外部碎片每个进程平均只产生半个块大小的内部碎片。

    内存空间:页框=页帧=内存块=物理块=物理页面。

    进程的逻辑地址空间:页=页面

    给它们编号之后它们的编号也是对应的。

    操作系统以页框为单位为各个进程分配内存空间。进程的每个页面分别放入一个页框中。进程的页面和内存的页框一一对应的关系。各个页面不必连续存放,可以放到不相邻的各个页框中,这正是离散分配方式的特点。 

    地址结构 

    在计算机内部,地址是用二进制表示的,如果页面大小刚好是2的整数幂,则计算机硬件可以很快速地把逻辑地址拆分成页号页内偏移量(页内地址)。 

    页面大小=物理块大小=页内地址位数=逻辑地址结构=页内偏移量位数。“=”的意思在这里是这些概念是可以互相求得的。

     当然下面这两个公式在页面大小不是2的整数幂时也是适用的:

    然后通过页号查询页表,可知页面在内存中的起始地址。

    页面在内存中的起始地址+页内偏移量=实际的物理地址

    引入页表

    引入页表这一数据结构来找到进程的每个页面在内存中的位置。每个进程都有一张页表且存在于内存中。

    即页表的作用是实现从(虚)页号到物理块号的地址映射。

    页表的页号是隐藏(类似数组),所以存储页表时不用考虑页号。

    而内存块大小=页面大小,假设内存块大小为2^20,假设计算机以字节分配地址空间,我们至少需要三个地址单元即3B=24位来表示块号。因此每个页表项占3B。

    那么通过查询页表寄存器得到页表初始地址后如何访问想找的虚页号对应的页表项   虚页号 i 的地址= F + 3 * i(F为页表在内存中的初始地址,3为每个页表项占3个字节空间)。

    然后得知物理块号,我们有了物理块号J之后如何在内存中找到想要的内存块地址呢?内存块J的地址=J*内存块大小(页面大小、物理块大小)

    对页表项长度的进一步讨论

    为了使i号页表项地址=页表在内存中始地址F+3*i这个公式成立,整个页表的页表项必须是在内存中地址连续地存储。但实际上可能会发生下面这种情况:

     

     解决方法是让每个页框正好存放整数个页表项,所以可以让页表项长度为4B。

    页表项长度和页面大小辨析

    • 上图红色整体是一个页表
    • 黄色为其中一个页表项
    • 页表项长度为页表项所占的存储空间的大小,上图为5bit,事实上必须是8的整数倍。
    • 页表长度表示页表总共有几个页,上图为3
    • 页面大小=物理块大小:为一个页占存储空间的大小。

    注:页面大小和页表项长度容易混淆,页面大小是根据进程的平均大小、页表长度等因素划分的。页表项长度是用来指示“页面对应的物理块”在内存中的编号。

    1.2.4.2.1基本地址变换机构

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

    1.2.4.2.2具有快表的地址变换机构 

    快表,又称联想寄存器(TLB,translation lookaside buffer),是一类cache,用来存放最近访问的页表项的副本,加快地址变换的速度。与此对应,内存中的页表称为慢表

    1.2.4.2.3二级页表

     问题一:页表必须连续存放,因此当页表很大时,需要占用很多个连续的页框。

    根据对分页管理方式的思想将原来的较长的页表进行分页。 

     补充:若采用多级页表机制,除一级页表的各级页表的大小不能超过一个页面。

    问题二:没有必要让整个页表常驻内存,因为进程在一段时间内可能只需要访问某几个特定的页面。

    可以在需要访问页面时才把页面调入内存(虚拟存储技术)。可以在页表项中增加一个标志位,用于表示该页面是否已经调入内存。

     

    1.2.4.3基本分段存储管理

    分段 

    进程的地址空间:按照程序自身的逻辑关系划分为若干个段,每个段都有一个段名(在低级语言中,程序员使用段名来编程),每段从0开始编址。

    内存分配规则:以段位单位进行分配,每个段在内存中占据连续空间,但各段之间可以不相邻。

    • 段号的位数决定了每个进程最多可以分几个段。
    • 段内地址位数决定了每个段的最大长度是多少。

    段表 

     

    • 每个段对应一个段表项,其中记录该段在内存中的起始位置(又称基址)段的长度。而页表项中记录的是块号,并且不记录段的长度。
    • 各个段表项的长度是相同的
    • 段号是隐含的,不占存储空间。 

    1.2.4.3.1基本地址变换机构

     第一次访存,查内存中的段表,第二次访存,访问目标内存单元。

    1.2.4.3.2段的共享与保护 

    分段比分页更容易实现信息的共享和保护。

    不能被修改的代码称为纯代码可重入代码(不属于临界资源),这样的代码是可以共享的。

    而可修改的代码是不能共享的(比如,有一个代码段中有很多变量,各进程并发地同时访问可能造成数据不一致)

     

    1.2.4.4段页式管理 

    • 段号的位数决定了每个进程最多可以分几个段
    • 页号位数决定了每个段最大有多少页(即最大段长)
    • 页内偏移量决定了页面大小=内存块大小是多少

    段页式管理中,“分段”对用户是可见的,程序员编程时需要显式地给出段号、段内地址。而将各段“分页”对用户是不可见的。系统会根据段内地址自动划分页号和页内偏移量。因此段页式管理的地址结构是二维的 

    1.2.4.4.1基本地址变换机构 

    注意这里的段表和段式管理方式的段表的不同。 

     

      第一次访存,查段表;第二次访存,查页表;第三次访存,访问目标内存单元。

    页表和段表同样存储在内存中,系统提供给用户的物理地址空间为总空间大小减去页表或段表所占空间大小。 

    1.2.4.5三种离散分配方式对比

    页是信息的物理单位,对用户是不可见的。

    段是信息的逻辑单位,对用户是可见的。 

    分页的用户进程地址空间是一维的。

    分段的用户进程地址空间是二维的。

    段页式的用户进程地址空间是二维

    在不引入快表和多级页表时:

    分页二次访存,分段二次访存,段页式三次访存。


  • 相关阅读:
    一种管理KEIL工程输出文件的方法
    9.13校招 实习 内推 面经
    RustGUI学习(iced)之小部件(一):如何使用按钮和文本标签部件
    垃圾收集器ParNew&CMS与底层三色标记算法
    Android EditText 实现强制性弹出只能输入英文的键盘
    Hive基础5
    Response handling between UVM Driver and Sequencer for Pipelined Protocols
    游戏:逢7过
    MySQL事务详解
    鸿蒙Harmony应用开发—ArkTS声明式开发(触摸交互控制:触摸测试控制)
  • 原文地址:https://blog.csdn.net/weixin_74059671/article/details/128166494