内存管理(笔记)

本文详细介绍了内存管理的背景、连续内存分配(包括固定分区和变长分区)、可变分区、分段内存管理(涉及分段地址翻译和分段技术优缺点)、以及分页内存管理(包括页表和多级页表),探讨了地址翻译中的页表和TLB优化。
摘要由CSDN通过智能技术生成

内存管理

背景

  • 创建进程首先要将程序和数据装入内存。将用户源程序变为可在内存中执行的程序,通常需要编译、链接、装入三个步骤
  • 可执行程序经过编译产生了逻辑地址,为了提高进程的并发和内存利用 率,逻辑地址和运行物理地址间需要地址转换。程序装载进内存在运行时重定位,重定位就是物理地址到逻辑地址的一个过程。
  • 嵌入式操作系统多数内存管理非常简单,甚至没有内存管理。
  • PC和服务器、分布式等现代操作系统基本都支持虚拟内存管理。

内存分配和管理方案

连续内存分配

固定分区–等长分区
  • 操作系统初始化时将内存等分成k个分区
bool AvailSec[k]; int SecSize;
内存请求算法 //进程创建时
1. if(reqSize>SecSize) exit
2. 找出AvailSec[i]为真的i
3. 如果有,返回分区i的基址
4. 否则,将current加入请求队列等待
固定分区–变长分区
  • 初始化时将内存分成k个大小不同的分区
struct Section AvailSec[k];
内存请求算法 //进程创建时
1. if(reqSize>MaxSize) exit
2. 找出AvailSec[i].Size>reqSize且
AvailSec[i].Size最小的空闲分区i
3. 如果有,返回分区i的基址
4. 否则,将current加入请求队列等待
可变分区

根据reqSize(请求大小)进行动态分割

内存请求算法 //进程创建时
1. if(reqSize>内存大小)exit
2. if(reqSize>空闲空间总尺寸)
将current加入请求队列等待
3. 从空闲分区划出一个reqSize,并返回
其基地址 //那个空闲分区
4. 修改分区数据结
可变分区数据结构

在这里插入图片描述

新的内存请求:reqSize = 100K

在这里插入图片描述

进程2执行完毕,释放内存

在这里插入图片描述

分区分配算法
  • 首次适配:分配首次找到的满足要求的空闲分区。特点:快
  • 最佳适配:查找最小的满足要求的空闲分区。特点:
    • 1)搜索整个空闲分区,慢
    • 2)会产生许多小的空闲分区
  • 最差适配:查找最大的满足要求的空闲分区。
    • 1)搜索整个空闲分区,慢
    • 2)新产生的空闲分区大一些。
碎片问题
  • 碎片:内存中剩余的无法使用的存储空间
  • 外部碎片:随着进程不断的装入和移出,对分区不断地分割,使得内存中产生许多特别小的分区,它们并不连续可用
  • 内部碎片:对固定分区来说,被分配给某个进程的分区中未被占用的空间,是无法分给其他进程的
  • 碎片问题可以消除(内存紧缩),但时间成本太高
外部碎片处理–内存紧缩

将空闲分区合并在一起,需要移动进程(复制内容)

但内存紧缩需要花费大量时间,连续分配技术并不合适。

分段内存管理

程序有主程序、变量集、函数库、动态数组、栈等部分,不同部分有各自的用途,可以考虑不同部分分为不同的段。

在这里插入图片描述

但这样一来一个进程需要记录多个基址,且仍需要内存分区表和内存分配算法

分段地址翻译

分段地址由<段号,段内偏移>确定,其中:
段号 = I N T [ 逻辑地址 / 逻辑段大小 ] 偏移 = [ 逻辑地址 ] % 逻辑段大小 段号=INT[逻辑地址/逻辑段大小]\\ 偏移=[逻辑地址]\%逻辑段大小 段号=INT[逻辑地址/逻辑段大小]偏移=[逻辑地址]%逻辑段大小
在这里插入图片描述

分段技术总结
  • 将程序按含义分成若干部分,即分段
  • ld从0开始编址每个段(链接速度会很快):汇编时从0编址、链接时可不为0
  • 创建进程(分别载入各个段)时,建立进程段表
  • 内存仍用可变分区进行管理,载入段时需调分配算法
  • PC及数据地址要通过段表算出物理地址,到达内存
  • 进程切换时,进程段表也跟着切换
分段技术优缺点
优点:
  • 不同的段有不同含义,可区分对待
  • 每个段独立编址,编址容易
缺点:
  • 空间预留;空闲空间很大却不能分配;内存紧缩

分页内存管理

将内存分为小块的页,一次只分配给一点(没有外部碎片,内部碎片有上限)。

在这里插入图片描述

页表

在这里插入图片描述

  • 页的逻辑地址由页号和页内偏移组成,其中页号的范围取决于页的数量,页内偏移的范围取决于页面的尺寸。
  • 进程页表中记录着页号与页框号的映射关系,当需要查找某个页时需要去进程页表中查找该页所在的页框号,再去对应页框号查找到该页。
分页地址翻译

在这里插入图片描述

  • PCB中记录着该进程对应的页表指针
  • 逻辑地址翻译为物理地址,用页号去页表查找页框号,页框号和偏移组成物理地址。
一些细节问题
  • 和段表不一样,页表可能会很大
  • 页是用来解决碎片问题的=>页面尺寸应尽量小
  • 页面尺寸通常为4K,32位机器有 2 20 2^{20} 220个页面,因为低12位是偏移
  • 每条指令都要查几次页表,因此查表效率很重要
页表项数据结构

Page Table Entry(PTE)

Intel x86结构的PTE

unsigned translate(unsigned va, int wr){
    struct pte *pte = &page_table[va >> 12]; // 页号
    if(!pte->valid || (wr && !pte->writeable))
        throw address_fault;
    return (pte->ppn << 12) | (va & 0xfff);
}
习题

例1:已知某分页系统,主存容量为64k,页面大小为1k,对一个4页大的 作业,第0、1、2、3页被分配到内存的2、4、6、7块中。求:将十进制的 逻辑地址1023、2500、4500转换成物理地址。

  1. 1023/1K,得到页号为0,页内地址1023。 又 对应的物理块号为2,故物理地址为2*1k+1023=3071
  2. 2500/1K,得到页号为2,页内地址452 又 对应的物理块号为6,故物理地址为6*1k+452=6596
  3. 4500/1K,得到页号为4,页内地址404 因为页号不小于页表长度,故产生越界中断

设有8页的逻辑空间,每页有1024字节,它们被映射到32块的物理存储区 中,那么逻辑地址的有效位是_位,物理地址至少是__位。

  • 逻辑地址有两个部分组成:页号和页内偏移地址。逻辑空间有8 ( 2 3 2^3 23)页, 说明页号需要3个二进制位描述,而每页有1024( 2 20 2^{20} 220)字节,说明页内偏 移地址为10二进制位描述,因此逻辑地址的有效位为3+10=13位。
  • 因为物理地址与逻辑地址的页面大小相同,而物理存储块为32( 2 5 2^5 25)占5 位,所以物理地址至少为5+10=15位
多级页表
  • 2 20 2^{20} 220个页表项,每个4字节,都放在内存,要4M内存
  • 实际上大部分逻辑地址根本不会用到
  • 引入多级页表,顶层页表常驻内存,不需要映射的逻辑地址不需要建立页表项

在这里插入图片描述

多级页表地址翻译

在这里插入图片描述

TLB
  • 多级页表地址翻译效率很低,要提高效率
  • TLB(Translation Look-aside Buffer)是一组关联快速寄存器组
采用TLB后的地址翻译

在这里插入图片描述

TLB命中时效率会很高,未命中效率会降低,平均后仍表现良好。
有效访问时间 = H i t R × ( T L B + M A ) + ( 1 − H i t R ) × ( T L B + 2 M A ) 有效访问时间 = HitR\times(TLB+MA)+(1-HitR)\times(TLB+2MA) 有效访问时间=HitR×(TLB+MA)+(1HitR)×(TLB+2MA)
其中 H i t R HitR HitR是命中率,TLB是访问TLB时间,MA是内存访问时间。

因此TLB要发挥作用,命中率应尽可能高,即TLB越大越好,但TLB价格昂贵,通常条目数在[64, 1024],根据局部性,64就能发挥作用了。

TLB动态变化
  • 如果TLB未命中,可将查到的页表项载入TLB
  • 如果TLB满了,需要选择一个条目来替换
  • 有时候希望某些条目能够固定下来(如内核代码),某些TLB的设计有这样的功能
  • 进程切换以后,所有的TLB表项都变为无效
  • 如果进程马上又切换回来,则这种策略会很低效,有的TLB设计中条目项保存ASID(Address-space identifer)
分页技术总结
实现机理
  • 逻辑地址空间和内存都分割大小相等的片(页和页框)
  • 每个进程用页表(多级、反向等)建立页和页框的映射
  • 进程创建时申请页,可用表、位图等结构管理空闲页
  • 逻辑地址通过页表算出物理地址,到达内存
  • 进程切换时,页表跟着切换
优点
  • 靠近硬件,结构严格,高效使用内存
缺点
  • 不符合程序员思考习惯

段、页结合

段面向用户,页面向硬件

在这里插入图片描述

实现机理
  • 程序的段划分的是线性地址空间
  • 线性地址空间和内存被分割大小相等的片(页和页框)
  • 进程用页表建立页和页框的映射
  • 进程创建申请段(线性地址空间),段申请页(物理内存)
  • 逻辑地址通过段表加页表算出物理地址,到达内存
  • 进程切换时,段表和页表都跟着切换
优点
  • 符合程序员习惯,并可高效利用内存
缺点
  • 复杂,访问一次地址需要查表多次

进行一次地址翻译需要:

  1. 找到段表;2) 查段表; 3)找TLB;4)找到页目录表;5)查找页目录项;6)找到页表;7)查找页表;8)形成物理地址;9)需要段越界检查;10)需要进行段保护权限检查;11)需要进行页保护权限检查…

习题

多进程在主存中彼此互不干扰的环境下运行,操作系统是通过(B) 来实现的。

A.内存分配 B.内存保护 C.内存扩充 D.地址映射

解析:多进程的执行通过内存保护实现互不干扰,如页式管理中有页地址越界保护,段式管理中有段地址越界保护

  1. 下列关于页式存储的论述中,正确的是(A)。

I.在页式存储管理中,若关闭 TLB,则每当访问一条指令或存取 一个操作数时都要访问 2 次内存

Ⅱ.页式存储管理不会产生内部碎片

Ⅲ.页式存储管理中的页面是为用户所感知的

Ⅳ.页式存储方式可以采用静态重定位

A. 仅 I B.I、Ⅳ C:I、Ⅱ、Ⅳ D.全都正确

解析: I 正确:关闭 TLB 后,每当访问一条指令或存取一个操作数时都要先 访问页表(内存中),得到物理地址后,再访问一次内存进行相应操 作。 Ⅱ错误:凡是分区固定的都会产生内部碎片,而无外部碎片。 Ⅲ错误:页式存储管理对于用户是透明的。 Ⅳ错误:静态重定位是在程序运行之前由装配程序完成的,必须分配 其要求的全部连续内存空间。而页式存储管理方案是将程序离散地分 成若干页(块),从而可以将程序装入不连续的内存空间,显然静态 重定位不能满足其要求。

某操作系统采用段式管理,用户区主存为 512KB,空闲块链入空 块表,分配时截取空块的前半部分(小地址部分).初始时全部空 闲。执行申请、释放操作序列 reg(300KB),reg(100KB),release (300KB),reg(150KB),reg(50KB),reg(90KB):

1.采用最先适配,空块表中有哪些空块?(指出大小及始址)

最先适配的内存分配情况如下图中的(a)所示。

内存中的空块为: 第一块:始址 290K,大小 10KB;第二块:始址 400K,大小 112KB。

(过程就是一开始300KB存在0-300KB,然后100KB存在300-400KB,然后释放300KB,150KB存在0-150KB,50KB存在150-200KB,90KB存在200-290KB)

2.采用最佳适配,空块表中有哪些空块?(指出大小及始址)

最佳适配的内存分配情况如下图中的 b)所示。

内存中的空块为: 第一块:始址 240K,大小 60KB;第二块:超始地址 450K,大小 62KB。

3.若随后又要申请 80KB,针对上述两种状况会产生什么后果?

若随后又要申请 80KB,则最先适配算法可以分配成功,而最佳适配算 法则没有足够大的空闲区分配。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值