存储器管理——内存分配(分区,段,页)

存储器管理

连续分区两种方式对比

固定分区 可变分区
分区内存大小 固定 可变
内存利用率 提高
内碎片 存在 不存在
外碎片 不存在 存在
碎片解决方案 紧缩技术
并发程序个数 固定 可变
内存管理数据结构 内存分配表 分区链表
内存分配策略 最先/最佳匹配法 最先/最佳/最坏/下次匹配法
内存回收策略 分区状态 占用 => 空闲 更新分区链表
内存保护策略 限长寄存器 限长寄存器

内碎片:进程所占用的分区内部未被利用的空间
外碎片:各进程之间难以被利用的空闲区间

不变分区两种策略

单个输入队列的

最先匹配法 最佳匹配法
解释 找第一个可以装入该分区的 搜索整个队列,选择能装入的该分区的最大进程
优/缺点 小进程可能浪费大的空间 减少空间的浪费

可变分区四种策略

最先 最坏 最佳 下次
解释 找第一个 找最大的 找大小最为接近,使得外碎片最小 从上次找的地方再找找不到循环到前面去
优点 速度很快,高地址较大分区易于保留 不留下小的空闲分区 速度快,分布均匀
缺点 大分区没有保留下来 外碎片浪费 大分区不易保留

理解重定位

物理地址:内存地址,绝对地址,实地址
逻辑地址:相对地址,虚地址
地址映射 (地址重定位) :逻辑地址 ->物理地址

静态重定位 动态重定位
区别 载入内存的时候指令地址固定 运行的时候指令地址固定
移动 此段程序载入内存后不可以移动 此段程序载入内存后可以移动
需求 不需要寄存器 需要基址寄存器

段页存储对比

页式存储 段式存储
数据结构 页表 & 物理页面表 段表
逻辑页号 & 内存块号(物理页面号) 段号 & 段起始地址 & 段长& 保护位
优点 没有外碎片,内碎片也很小 分为多个模块,实现每个模块分别编写,编译,保护,段单位共享
程序不必连续存放 程序不必连续存放
缺点 程序必须全部装入内存 程序必须全部装入内存
维护页表也是一笔开销 存在外碎片

1. 页存储理解

因为是动态重定位:所以给出的是逻辑地址 高位变成逻辑页面号(数组下标) 低位则为页内偏移
理解为什么可以转换:
程序以动态重定位方式进行,假如给的是8位逻辑地址,假如内存被分为16字节一个块,一共16个页
从 0000 | 0000 到 1111|1111
0000 | 0000 第零页的开始
0000 | 0011 第零页的0011偏移量
0000 | 1111 第零页的最后一块 下一个内容就要翻一页了
0001 | 0000 第一页开始 同理
0001 | 1111 需要翻页了
0002 | 0000 就是第二页
假如给出的逻辑地址 0001 | 1111 现在知道页数了
那么要找到物理块号 我们还有两个问题
1.他是谁的第一页?
2.页表放在哪里?
但一个进程建立都给出了页表,那么当这个进程运行的时候,他会把他的页表的起始地址放在基址寄存器中,所以 第二个问题就解决了,第一个问题当然也解决了,你需要访问的是在占用CPU的,这时候你寄存器里存的页表起始地址就是他的第一页,最后一个问题?
他是表里面的哪一个?因为这样才能找到块号
页表起始地址+页号(右偏移四位)或 页表起始地址+页面大小*页号
式子就是他 ,找到相应块号,然后转换成物理地址 假如块号就是3 然后毕竟是 0011|1111
这样完成了逻辑地址到物理地址转换

这样的坏处
两次访问内存,CPU访问内存相当慢
解决方案
于是有了TLB 存放最近一段时间最常用的页表项, 逻辑页面号与 物理页面号直接对应

2. 段存储的理解

段存储给出逻辑地址的本身就二维地址
同样知道 假如给的是0001 | 1111 第一维段号 第二维段内偏移 同样知道第一段
两个问题?
1.他是谁的第一段?
2.段表放在哪里?
但一个进程建立都给出了段表,那么当这个进程运行的时候,他会把他的段表的起始地址放在基址寄存器中 还有个问题
他是表里面的哪一个?
段表起始地址+段号(右偏移四位)
找到段的起始地址 多出来的操作就是 偏移量与得到段长比 是否越界!
段起始地址+偏移地址 就是物理地址

是不是两者很像 主要是因为逻辑地址含义不一样而已
段还有一种 ,学过8086处理器的知道
是直接在CS ,DS,SS,ES给出段起始地址 的

猜你喜欢

转载自blog.csdn.net/qq_42146775/article/details/84853595