热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

OS学习笔记:内存管理

四、内存管理1.内存管理的基本概念操作系统对内存的划分和动态分配程序的编译由编译程序将用户源代码编译成cpu可执行的目标代码(.o文件)ÿ

四、内存管理


1.内存管理的基本概念

操作系统对内存的划分和动态分配

img

程序的编译

由编译程序将用户源代码编译成cpu可执行的目标代码(.o文件),产生了若干个目标模块(即若干程序段)。


程序的链接

根据外部访问符号名表(如变量名、函数名等),将经过编译或汇编 得到的一组目标模块以及它们所需要的库函数,装配成一个完整的装入模块


静态链接

下图B和C都属于外部调用符号,在将这几个目标模块装配成一个装入模块时,须解决以下两个问题:

(1) 对相对地址进行修改。

(2) 变换外部调用符号。

img

这种先进行链接所形成的一个完整的装入模块,又称为可执行文件。通常都不再拆开它,要运行时可直接将它装入内存。这种事先进行链接,以后不再拆开的链接方式,称为静态链接方式。


装入时动态链接(所有的模块都装入内存)

用户源程序经编译后所得的目标模块,是在装入内存时边装入边链接的, 然后再按照上图所示的方式来修改目标模块中的相对地址。

优点:


  1. 便于修改和更新。对于经静态链接装配在一起的装入模块,如果要修改或更新其中的某个目标模块,则要求重新打开装入模块。这不仅是低效的,而且有时是不可能的。若采用动态链接方式,由于各目标模块是分开存放的,所以要修改或更新各目标模块是件非常容易的事。
  2. 便于实现对目标模块的共享。在采用静态链接方式时,每个应用模块都必须含有其目标模块的拷贝,无法实现对目标模块的共享。但采用装入时动态链接方式,OS则很容易将一个目标模块链接到几个应用模块上,实现多个应用程序对该模块的共享。

运行时动态链接(需要某个模块时才装入内存)

在许多情况下,应用程序在运行时,每次要运行的模块可能是不相同的。但由于事先无法知道本次要运行哪些模块,故只能是将所有可能要运行到的模块都全部装入内存,并在装入时全部链接在一起。显然这是低效的,因为往往会有些目标模块根本就不运行。比较典型的例子是作为错误处理用的目标模块,如果程序在整个运行过程中都不出现错误,则显然就不会用到该模块。


在执行过程中,当发现一个被调用模块尚未装入内存时,立即由OS去找到该模块并将之装入内存,把它链接到调用者模块上。凡在执行过程中未被用到的目标模块,都不会被调入内存和被链接到装入模块上,这样不仅可加快程序的装入过程,而且可节省大量的内存空间。

####程序的装入

由装入程序将装入模块装入内存,构造PCB,形成进程,开始运行(使用物理地址)。


绝对装入方式

在编译时,如果知道程序将驻留在内存的什么位置,那么,编译程序将产生绝对地址的目标代码。 绝对装入程序按照装入模块中的地址,将程序和数据装入内存。 装入模块被装入内存后,由于程序中的逻辑地址与实际内存地址完全相同,故不须对程序和数据的地址进行修改。程序中所使用的绝对地址,既可在编译或汇编时给出,也可由程序员直接赋予。

注:
由于内存划分为系统区和用户区,程序实际在用户区执行,故实际上程序的实际内存地址也有一定的增加,不可能像逻辑地址一样从0开始。


  • 优点:使CPU执行目标代码快
  • 缺点:
    1. 由于内存大小限制,能装入内存并发执行的进程数大大减少
    2. 编译程序必须知道内存的当前空闲地址部分和其地址,并且把进程的不同程序段连续地存放起来,编译非常复杂。

静态地址重定位

绝对装入方式只能将目标模块装入到内存中事先指定的位置。在多道程序环境下,编译程序不可能预知所编译的目标模块应放在内存的何处,因此,绝对装入方式只适用于单道程序环境

在多道程序环境下,所得到的目标模块的起始地址通常是从 0 开始的,程序中的其它地址也都是相对于起始地址计算的。此时应采用可重定位装入方式,根据内存的当前情况,将装入模块装入到内存的适当位置。


静态地址重定位:即在程序装入对目标代码装入内存的过程中完成,是指在程序开始运行前,程序中指令和数据的各个地址均已完成重定位,即完成虚拟地址到内存地址映射。地址变换通常是在装入时一次完成的,以后不再改变

img


  • 优点:无需硬件支持
  • 缺点:
    1. 程序重定位之后就不能在内存中搬动了;
    2. 要求程序的存储空间是连续的,不能把程序放在若干个不连续的区域中。

动态地址重定位

可重定位装入方式可将装入模块装入到内存中任何允许的位置,故可用于多道程序环境;但这种方式并不允许程序运行时在内存中移动位置。因为,程序在内存中的移动,意味着它的物理位置发生了变化, 这时必须对程序和数据的地址(是绝对地址)进行修改后方能运行。然而,实际情况是,在运行过程中它在内存中的位置可能经常要改变,此时就应采用动态运行时装入的方式。


动态地址重定位:不是在程序执行之前而是在程序执行过程中进行地址变换。更确切的说,是把这种地址转换推迟到程序真正要执行时才进行,即在每次访问内存单元前才将要访问的程序或数据地址变换成内存地址。动态重定位可使装入模块不加任何修改而装入内存。为使地址转换不影响指令的执行速度,这种方式需要一个重定位寄存器的支持。

img

优点:


  1. 目标模块装入内存时无需任何修改,因而装入之后再搬迁也不会影响其正确执行,这对于存储器紧缩、解决碎片问题是极其有利的;
  2. 一个程序由若干个相对独立的目标模块组成时,每个目标模块各装入一个存储区域,这些存储区域可以不是顺序相邻的,只要各个模块有自己对应的定位寄存器就行。

缺点:需要硬件支持。


逻辑地址和物理地址空间

程序经过编译后,每个目标模块都是从0号单元开始编址,称为该目标模块的相对地址(或逻辑地址)。

物理地址空间是指内存中物理单元的集合,它是地址转换的最终地址,进程在运行时执行指令和访问数据都要通过物理地址从主存中存取。当装入程序(Loader)将可执行代码装入内存时,必须通过地址转换将逻辑地址转换成物理地址,这个过程称为地址重定位


对换与覆盖

覆盖与对换技术是在多道程序环境下用来扩充内存的两种方法。

覆盖与对换可以解决在小的内存空间运行大作业的问题,是“扩充”内存容量和提高内存利用率的有效措施。

覆盖技术主要用在早期的 OS 中,对换技术则用在现代OS 中。


对换

摘自:操作系统存储器管理之覆盖与对换

所谓“对换” ,是指将暂时不用的某个进程及数据(首先是处于阻塞状态优先级最低的)部分(或全部)从内存移到到外存(备份区或对换区)中去,让出内存空间,同时将某个需要的进程调入到内存中,让其运行。

交换技术也是“扩充”内存容量和提高内存利用率的有效措施。

交换到外存的进程需要时可以被再次交换回(选择换出时间最久的)内存中继续执行。

图示

对换的类型


  • 整体对换:进程对换,解决内存紧张问题。 (中级调度)
  • 部分对换:页面对换/分段对换,提供虚存支持。

对换空间的管理


  • 具有对换功能的 OS 中,通常把外存分为文件区和对换区。前者用于存放文件,后者存放从内存换出的进程。对换区比文件区侧重于对换速度。因此对换区一般采用连续分配。

进程的换出与换入


  • 选择换出进程:优先级,进程状态。
  • 选择换入进程:优先级,进程状态,换出时间等。

重定位


2.连续内存分配方法

连续分配:程序中代码或数据的逻辑地址相邻,体现在内存空间分配时物理地址的相邻


2.1单一连续分配


  • 简单,无外部碎片
  • 只能用于单用户、单任务的操作系统,有内部碎片

2.2固定连续分配


  • 无外部碎片
  • 有内部碎片,存储空间利用率低

2.3动态分区分配


  • 无内部碎片,有外部碎片
  • 动态分区的分配策略(★★★★★)
  • 首次适应(★★★★):按地址从小到大依次寻找空闲分区,将第一个能满足要求的空闲分区分配给程序
  • 最佳适应:按容量从小到大依次寻找空闲分区,将第一个能满足要求的空闲分区分配给程序
  • 最坏适应(最大适应):按容量从大到小依次寻找空闲分区,将第一个能满足要求的空闲分区分配给程序
  • 邻近适应(循环首次适应):与首次适应类似,但是查找开始位置上一次查找结束的位置
  • 动态分区的分配策略的比较
    • 首次适应,简单,最好、最快

3.1离散内存分配方法(分页、分段、段页)


3.1.1分页

#####逻辑地址到物理地址的转换

逻辑地址到物理地址的转换(不含快表)

img


  • 设页面大小为 L,逻辑地址A 到物理地址E的转换
    1. 分析出页号和页面偏移量(根据题设地址结构或者计算得出):计算页号 P ( P = A / L )和页面偏移量 W (W = A % L )
    2. 判断页号合法性:比较页号 P 和页表长度 M ,若 PM ,则产生越界中断,否则继续执行。
    3. 查页表,得块号:页表中页号 P 对应的页表项地址(目的是在内存中找到相应的页表项) = 页表始址 F + 页号 P × 页表项长度,取出该页表项内容 b ,即为物理块号。(注意区分页表长度页表项长度页表长度的值指一共有多少页,页表项长度是指页地址占多大的存储空间)
    4. 拼接块号和页内偏移量:计算 E = b × L + W ,用得到的物理地址 E 去访问内存

逻辑地址到物理地址的转换(含快表)

img


  • 含快表的地址变换流程
    1. CPU 给出逻辑地址后,由硬件进行地址转换,将页号送入高速缓存寄存器,并将此页号与快表中的所有页号进行比较
    2. 若能找到匹配的页号,说明所要访问的页表项在快表中,则直接从中取出该页对应的块号,和页内偏移量拼接形成物理地址。(仅一次访存就可以存取数据)
    3. 若未找到,类似不含快表对逻辑地址进行转换,并把(页号,块号)对存入快表。若快表已满,则需依据相应的替换算法对快表中的元素进行替换

多级页表

  • 试和索引表比较一下
  • 多级和一级的对比
    • 一级页表,其存储页号到块号的存储极限取决于其本身的长度
    • 多级页表,其存储页号到块号的存储极限取决于各级页表长度之积
    • 总结:乘法比加法更能压缩空间
  • 以二级为例,分析其中的数据关系(注意举一反三)(★★★★★)
    • 32 位 逻辑地址空间、页面大小 4 KB、页表项 4 B,以字节为编址单位,试确定满足二级页表的逻辑地址空间格式(即求哪几位代表一级页号、二级页号、页内偏移)
      • 页内偏移位数 = log2页面大小log_2页面大小log2页面大小 (本例即 log24K=12log_24K=12log24K=12)
      • 由于顶级页表最多一个页面,故顶级(一级)页表总共能容纳 页面大小页表项大小页面大小/页表项大小 个页表项(本例为 4KB/4B = 1K),所需位数为 页表项个数log2(页表项个数)log_2(页表项个数)log2(页表项个数) (本例为log2(1K)=10log_2(1K)=10log2(1K)=10)
      • 剩下的 10 位,即为二级页号。
      • 所以逻辑地址空间格式如下

一级页号(10 位)二级页号(10 位)页内偏移量(12 位)

3.1.2分段(两次访存)

img


  • 逻辑地址A到物理地址E的转换
    1. 提取段号和页内偏移量:逻辑地址 A 的结构:前几位是段号 S ,后几位是段内偏移 W
    2. 判断段号合法性:比较段号 S 和段表长度 M ,若 SM ,则产生越界中断,否则继续执行
    3. 查段表,找到段基址、段长,并判段内偏移的合法性:段表中段号 S 对应的段表项地址 = 段表首址 F + 段号 S × 段表项长度,取出该段表项的前几位得到段长 C 。若段内偏移量 ≥ C,则产生越界中断,否则继续执行。
    4. 取出段基地址,和段内偏移求和:取出段表项中该段的基址 b ,计算 E = b + W

3.1.3段页(三次访存)

img


  • 逻辑地址A到物理地址E的变换

  1. 依据段号查段表,找到页表始址
  2. 依据页表始址页号查页表,得到块号
  3. 块号页面偏移量拼接成物理地址

3.2虚拟内存分配方法


虚拟内存

概念


虚拟记忆体是电脑系统记忆体管理的一种技术。它使得应用程式认为它拥有连续可用的记忆体(一个连续完整的位址空间),而实际上实体记忆体通常被分隔成多个记忆体碎片,还有部分暂时储存在外部磁碟记忆体上,在需要时进行资料交换。与没有使用虚拟记忆体技术的系统相比,使用这种技术使得大型程式的编写变得更容易,对真正的实体记忆体(例如RAM)的使用也更有效率。此外,虚拟记忆体技术可以使多个行程共享同一个执行库,并通过分割不同行程的记忆体空间来提高系统的安全性。



请求分页(段)管理

地址变换过程

img


页面置换算法


最佳(OPT)置换算法

  • 置换标准:淘汰最长时间内不再被访问的页面
  • 无法实现

先进先出(FIFO)置换算法

  • 置换标准:淘汰最早进入内存的页面(用队列实现)
  • 缺页率较高,会产生所分配的物理块数增大而页故障数反减的异常现象

最近最久未使用(LRU)置换算法

  • 置换标准:淘汰最近最久未使用的页面
  • 性能较好,但需要寄存器和栈的硬件支持。
  • 手算思路
    • 假想一个链表,其最大长度为内存中能存下最多页面的个数。
    • 若页面不在该链表中,且链表长度未超过最大长度,则将这个页面插入到链表头部
    • 若页面不在该链表中,且链表长度超过最大长度,则将链表末尾元素删除,并将新个页面插入到链表头部
    • 若页面在该链表中,则将新页面移动到链表头部,其他元素位置不变

时钟(CLOCK)置换算法(NRU,最近未用)

  • 置换标准:淘汰访问位为 0 的页面
    • (具体算法流程详见教材)
  • 改进的 CLOCK 算法:多增一位修改位。
    • 假设 A 为访问位, M 为修改位,(A, M)所有可能取值,淘汰顺序为
    • (0, 0) (0, 1) (1, 0) (1, 1) (优先换出未使用的;若全部都已使用,再考虑优先换出未被修改的)
    • (具体算法流程详见教材)

4.内存保护与共享

分段的共享和保护


共享段

为了实现分段共享,可在系统中配置一张共享段表,所有各共享段都在共享段表中占有一表项。表项中记录了共享段的段号、段长、内存.


分段保护

在分段系统中,由于每个分段在逻辑上是独立的,因而比较容易实现信息保护。目前常采用以下几种措施来确保信息的安全。


  1. 越界检查

    在段表寄存器中放有段表长度信息;同样,在段表中也为每个段设置有段长字段。在进行存储访问时,首先将逻辑地址空间的段号与段表长度

  2. 存取控制检查

    在段表的每个表项中,都设置了一个“存取控制”字段,用于规定对该段的访问方式。通常的访问方式有

  3. 环保护机构

    image-20220925154536831


5.抖动的概念和处理方法


概念


如果多道程度过高,页面在内存与外存之间频繁调度,以至于调度页面所需时间比进程实际运行的时间还多,此时系统效率急剧下降,甚至导致系统崩溃。这种现象称为颠簸或抖动(thrashing)



处理\预防方法


  • 采取局部置换策略
  • 在处理机调度中引入工作集策略
  • 用 L=S 准则调节缺页率(Denning, 1980)
  • 挂起若干进程

解题技巧与重要结论


  • 物理地址 VS 逻辑地址
    • 物理地址(实地址),若其位数为 32 位,意味着实际物理内存为 2322^{32}232B
    • 逻辑地址(虚地址),若其位数为 48 位,意味着对用户来说内存大小为 2482^{48}248B (采用了虚拟内存技术)
  • 含多级页表的逻辑地址的划分中的公式总结(对照教材中多级页表理解)
  • 页内偏移位数页面大小页内偏移位数=log2页面大小log_2页面大小log2页面大小
  • 页号部分总位数逻辑地址总位数页内偏移位数页号部分总位数=逻辑地址总位数逻辑地址总位数逻辑地址总位数页内偏移位数页内偏移位数页内偏移位数
  • 一级页号位数=页面大小页表项大小\frac{页面大小}{页表项大小}页表项大小页面大小
  • 页表级数=页号部分总位数一级页号位数\frac{页号部分总位数}{一级页号位数}一级页号位数页号部分总位数

推荐阅读
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
  • 本文介绍了2020年计算机二级MSOffice的选择习题及答案,详细解析了操作系统的五大功能模块,包括处理器管理、作业管理、存储器管理、设备管理和文件管理。同时,还解答了算法的有穷性的含义。 ... [详细]
  • 本文介绍了Redis中RDB文件和AOF文件的保存和还原机制。RDB文件用于保存和还原Redis服务器所有数据库中的键值对数据,SAVE命令和BGSAVE命令分别用于阻塞服务器和由子进程执行保存操作。同时执行SAVE命令和BGSAVE命令,以及同时执行两个BGSAVE命令都会产生竞争条件。服务器会保存所有用save选项设置的保存条件,当满足任意一个保存条件时,服务器会自动执行BGSAVE命令。此外,还介绍了RDB文件和AOF文件在操作方面的冲突以及同时执行大量磁盘写入操作的不良影响。 ... [详细]
  • 上图是InnoDB存储引擎的结构。1、缓冲池InnoDB存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理。因此可以看作是基于磁盘的数据库系统。在数据库系统中,由于CPU速度 ... [详细]
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 基于事件驱动的并发编程及其消息通信机制的同步与异步、阻塞与非阻塞、IO模型的分类
    本文介绍了基于事件驱动的并发编程中的消息通信机制,包括同步和异步的概念及其区别,阻塞和非阻塞的状态,以及IO模型的分类。同步阻塞IO、同步非阻塞IO、异步阻塞IO和异步非阻塞IO等不同的IO模型被详细解释。这些概念和模型对于理解并发编程中的消息通信和IO操作具有重要意义。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
  • 关于CMS收集器的知识介绍和优缺点分析
    本文介绍了CMS收集器的概念、运行过程和优缺点,并解释了垃圾回收器的作用和实践。CMS收集器是一种基于标记-清除算法的垃圾回收器,适用于互联网站和B/S系统等对响应速度和停顿时间有较高要求的应用。同时,还提供了其他垃圾回收器的参考资料。 ... [详细]
  • Android工程师面试准备及设计模式使用场景
    本文介绍了Android工程师面试准备的经验,包括面试流程和重点准备内容。同时,还介绍了建造者模式的使用场景,以及在Android开发中的具体应用。 ... [详细]
  • 篇首语:本文由编程笔记#小编为大家整理,主要介绍了软件测试知识点之数据库压力测试方法小结相关的知识,希望对你有一定的参考价值。 ... [详细]
author-avatar
肥zi斌_343
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有