内存使用,分段,分页

2021.11.10

分段

内存使用

将进程放入内存中
但程序放入内存的位置不定,因此在CPU取指时需要找到的地址不能仅根据程序内部的定义来寻找,也要根据在内存中的位置来改变

重定位

每次根据在内存中的位置和程序中定义的位置(相对位置)来计算真正应该寻找的位置
进程在装入内存后并不是一直存在于同一个地方
在这里插入图片描述
因此需要在运行时重定位

分段

每个程序存在不同的段,不应该将所有的段都存放在一起,因为例如变量集是可以增长的,而主程序是不变的,因此需要将程序分开。
在这里插入图片描述

分段存放

整个进程被分为不同的段,每个段都放在内存的不同位置中,接着用进程段表存储每个段的基址,通过相应段号查询进程表就可以得到物理地址。
在这里插入图片描述

LDT&GDT

将每个进程的每个段在内存上的基址保存在LDT表中,通过查阅这些表就可以得到进程段的物理内存
每个进程拥有自己的LDT,这些LDT都保存在各自的PCB中,并注册到GDT中
在这里插入图片描述

分页

2021.11.11
直接按照分段将进程放入内存中可能造成内存的碎片化,因此不能单纯按照程序中的段来进行进程的存放

可变分区

在申请完成内存后,有的进程不再需要使用内存,那么这块内存会被释放掉,这样的操作就有可能造成内存中存在着碎片,因此在剩下的空闲内存中,可以采取不同的申请内存方法

首先适配

直接找到首个适配的,查找快,不需要一个一个查找

最佳适配

选择空闲内存中与需要的内存大小最接近的,这样会导致内存碎片越来越小

最差适配

选择空闲内存中与需要内存大小差别最大的

内存紧缩

为了将空闲内存合并,需要将进程段移动,这样的做法代价太大

引入分页

如果空闲内存是很多小的碎片,则他们的总大小可能能满足需要的空间,但却无法完整地放入需要的程序段
将内存进行分页,每一页装入进程段的一部分,这样的做法可以更好地利用空间,也能避免碎片空间的产生
在这里插入图片描述

页表

如果将内存分页,然后将进程段分别放入页中,这样的做法无法直接像分段式一样直接找到程序中需要找到的代码段,因此需要对于每一个放入的页加上一个映射表
在这里插入图片描述

利用页号找到在内存中的页框号,再进一步查找程序中需要使用的命令的位置。
由于页的大小是固定的,因此,一个进程段当中的指令可以根据他在进程段中的相对位置,直接计算出会被分配到哪一页中,进而算出被分配在内存中的什么位置。

多级页表

分页操作虽然尽可能地减少了碎片空间出现的可能,但每个进程不可能全部恰巧塞入页中,因此还是会有一定的碎片出现,为了尽可能地减少内存碎片,页的大小应该尽可能地小,然而这样的做法会导致页的数量增加,页表就会变大,这样也会占据更大的内存
另一方面,在程序中,并不是所有的地址都被连续使用,可能出现某一页不存在需要调用的地址,如下图所示
在这里插入图片描述
这样的情况下,页表中不需要占据页号2这个项

只存放用到的页

这样的做法不是顺序连续存放,因此在找寻需要的页号对应的地址时需要查找到在页表中的位置再进行映射,这样做对于时间的浪费很大

多级页表

使用页目录(章)加页表(节)
利用页目录号先映射到页目录表中,然后通过页号再映射到页上,在这样的情况下,页目录中的空白区域是不用映射到真实的页表中,因此可以减少空间的占用
在这里插入图片描述

快表

多级页表要多次访问内存,先访问内存查找第一页表,再通过查到的页号查找第二表,因此引入快表
快表将常用的页号存储,这样就不用访问多级页表来多次查找页号
在这里插入图片描述

TLB优势

在这里插入图片描述
TLB的条目数可以设定在64-1024之间
因为程序对于地址的访问具有局部性,在同一段地址之间会经常访问
在这里插入图片描述
2021.11.13

段页结合

用户需要的内存管理:分段,将进程分为几个段,能够分别放入连续的内存
硬件需要的内存管理:分页,需要尽量减少内存碎片的出现

虚拟内存

将进程分段连续映射在虚拟地址中,再通过虚拟地址找到真正的物理地址,用户看来是进程被连续放入内存(虚拟内存)中
在这里插入图片描述

  1. 首先将进程分段,根据段号可以算出在虚拟内存中的基址
    在这里插入图片描述
  2. 再通过在虚拟地址中的基址计算出页号,通过页号得到页框号,再喝偏移结合得到真正的物理地址
    在这里插入图片描述

内存换入换出

用户在使用进程时,无法看到虚拟内存以外的内容,用户只能认为进程被连续地映射到虚拟内存中,而虚拟内存一般都大于实际的物理内存,因此在实际使用物理内存时,需要将其中的内存换入换出

内存换入

请求调页

MMU查询页表,如果发现需要的指令不在表中,就会发出缺页中断,然后再去磁盘中找寻需要的指令,再在内存中找出一个空闲页,将这个指令放入到内存中

内存换出

由于内存的大小是有限的,在请求调页的过程中,总会出现无法找到free page的情况,这时就需要将内存中的部分换出,如何选择需要换出的页也是操作系统中的一个主要算法

内存换出的算法
FIFO

先入先出,但如果遇到刚放入的页马上又要换出则不理想
缺页次数很多

MIN

选最远将要使用的页淘汰,这样的做法是缺页最少的方法,但由于操作系统无法预测到需要执行的操作,因此无法判断哪个是最远要使用的页,这种方法仅是理论最佳,是无法达到的方法

LRU

选最近一段时间没有使用的页淘汰,通过这种方式,尽量去预测最远要使用的页,尽可能达到类似于MIN的算法

LRU的实现

  1. 利用时间戳
    在这里插入图片描述
    这样的做法会导致每次都要去维护所有内存中的页的时间戳,在换出时还需要遍历得到最小值,时间开销很大
  2. 页码栈
    维护一个栈
    每次地址访问都要修改栈指针,实际代价仍然比较大

SCR算法

LRU的实现方法都需要很大的代价,因此一般也不会去准确地实现,通常采用近似的实现
SCR:Second Chance Replacement
在每一页中添加一个引用位(reference bit),通过硬件自动设置引用位,每访问一次都设为1,而在选择哪一位要淘汰时,顺序扫描这些引用位,如果是1则将其变为0,如果是0就直接淘汰
这样的做法每次将上一轮中置为0的页码淘汰,也就近似实现了LRU

CLOCK算法

在缺页很少的情况下,在首次缺页取出一个页码后,会经过较长时间再到下一次缺页,在这期间,所有的页码的引用位又会被置为1,到了下一次扫描时,再找到的缺页就是第一次取出的下一个页码,这样就成了FIFO算法
这个问题的原因是记录了太长的历史信息,因此需要定时地清除引用位
于是引入了新的扫描指针,这个指针要比顺序扫描引用位走的更快,他能够做到定时清楚引用位,将引用位置0,这样在缺页时,得到的就是最近一段时间内不被使用的页码
在这里插入图片描述

给进程分配的页框数

分配的页框数过多会导致内存的利用率就没用了
分配的页框过少会导致缺页中断次数太多

颠簸(抖动)

在这里插入图片描述
进程少时,每个进程都能分配到足够的页,这样加上CPU的并发,可以导致利用率上升
而进程太多时,每个进程分配的页减少,导致每一次调用进程都会出现缺页,进程总是在等待调页完成,从而导致利用率下降

分配方法

由于进程常使用的地址会集中在某一部分,因此,尽量让进程能够覆盖住进程的一个局部
采用工作集算法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值