内存管理功能
- 内存空间的分配与回收:由OS实现主存储器空间的分配和管理,让程序员摆脱存储转换的麻烦
- 地址转换: 多道程序中,程序逻辑地址和物理地址不可能一致,所以需要提供地址变换管理功能,吧逻辑地址转换为相应的物理地址
- 内存空间的扩充: 利用虚拟存储技术或者自动覆盖技术,从逻辑上扩充内存
- 存储保护: 保证各个作业在各自的内存空间内运行,互不干扰
程序装入和链接
创建进程首先要将程序和数据装入内存,将用户源程序变为可以在内存中执行的程序,通常以下几个步骤
- 编译,由编译程序将用户源代码编译成若干目标模块
- 连接,让链接程序将编译后的一组目标模块及所需要额库函数连接在一起,形成一个完整的装入模块
- 装入,由装入程序将装入模块装入内存运行
链接方式
- 静态链接:程序运行以前将各个目标模块和所需要的库函数连接成一个完整的运行程序,以后不再打开
- 装入时动态链接:源程序目标模块编译后,再装入内存时,边装入边链接
- 运行时动态链接:程序执行时。需要该目标模块才进行。优点:便于修改和更新,便于实现对目标模块的共享
内存装入模块方式
- 绝对装入:编译时产生绝对地址(逻辑地址和物理地址完全相同),只适合单道程序环境,灵活性差
- 可重定位装入(静态重定位):根据内存当前状况,将装入模块放入内存合适的位置。装入时对目标程序中的指令和数据修改的过程称为重定位,地址变换通常是在装入时一次完成,特点:一个作业装入内存,必须分配所有要求的内存空间,如果没有就不能装入,一旦装入,运行期间就不能再内存中移动,也不可以申请内存空间
- 动态运行时装入(动态重定位):程序在内存中移动时,需要采用这种方式。装入程序吧模块装入内存,不会立即把相对地址转换为绝对地址,当程序真正执行时才进行,装入内存后的均为相对地址,所以需要一个重定位寄存器,特点:可以将程序分配到不连续的存储区,程序运行之前可以装入部分代码,在运行期间,根据需要动态申请分配内存便于实现程序的共享
覆盖与交换
覆盖:在早期计算机中,解决内存容量小即使只有一个程序也导致进程放不下。基本思想:用户空间分为固定区和若干覆盖区,经常活跃的放在固定区,常驻内存,其他的按关系分段,要访问的放入覆盖区,其他的段置于外存
交换:基本思想:把处于等待状态的程序从内存移到辅存,把空间腾出来(换出),把准备好竞争CPU的调入内存(换入)
交换需注意
- 交换需要备份存储,快速磁盘,要足够大,并提供对内存映像的直接访问
- 执行时间 >交换时间
- 交换发生在内存空间吃紧,负荷降低就停止
连续分配管理方式
- 单已连续分配,内存划分系统区(OS使用,通常在低地址)和用户区(为用户提供的),优点:简单没有外部碎片,缺点:只能用于单用户,单任务的OS,有内部碎片,存储器利用率低
- 固定分区分配:
两种不同方法
- 分区去大小相等:缺乏灵活性
- 分区大小不相等:划分为多个较小,适量的等分区少量的大分区
固定分区用于多道程序设计的最简单的存储分配无外部碎片,无法实现多进程共享一个主存区,存储利用率低
- 动态分区分配:不预先划分内存,在进程装入内存时,根据进程大小动态建立分区,因此系统的分区大小和数目可变
动态分区开始时很好,但当分配的进程完成时,就会空闲,这样的空闲时零散的,产生越来越多的外部碎片,(可以通过紧凑技术和动态重定位寄存器,windows磁盘就有紧凑,时间开销会很长很长)
进程装入或换如主存,内存有很多足够的空闲快,分配哪一块的决策:
结果表明:首次适应效果反而最佳
非连续分配方式
基本分页存储管理方式
将主存划分为大小相等的且固定的块,快相对比较小,作为主存的基本单位,每个进程也以块为单位进行划分,进程在执行时以块为单位逐个申请主存的块空间
和固定连续分配的区别:块的大小相对小很多,进程也按照块划分,进程运行时安块申请主存空间并执行,由于块很小,产生的内部碎片也小(也叫页内碎片)
基本概念
- 页框(页帧,内存块,物理块,物理页面) :将内存划分为一个个分区,这个分区就是,
- 页大小:每个分区大小一般是2^N B这样计算机操作更方便运算
- 页框号: 每个页框有一个编号(从0开始)
- 页(页面) :进程的逻辑空间也划分为一个个的区
- 页号:进程的逻辑空间划分的区的编号(由于连续,可以不用记录,隐含)
- 页表项长度:每个页表项由页号(逻辑块中的编号,由于是连续的可以隐含)和块号(内存块的编号)组成,表示一个这样的数据所需要的大小
对应数据结构:页表
页表(一般位于进程PCB中) :
- 一个进程对应一个页表
- 每个进程的每个页面对应一个页表项
- 每个页表项由页号(逻辑块中的编号,由于连续,可以不用记录,隐含)和块号(内存块的编号)组成
逻辑块中的编号-》内存块的编号(逻辑空间-》绝对地址的映射) - 逻辑地址表示含义 :逻辑地址由页号p和页内偏移量组成
假设内存4GB,页面大小4KB;可以划分为4GB/4KB=2^20 个 页面,一个页面大小4KB=2^12B, 也就是在一个页面内的地址范围(0~2的12次方-1 );也就是页内偏移量,用12位表示;又包括了2 ^ 20个页面,也就是页号的范围从0到2^20-1;要表示这么多,在计算机中需要20位,加上前面的页内偏移量12位共计32位(逻辑空间32位表示刚好4字节);(补充:又因为计算机是以字节为单位,一个字节8B),
基本地址转换机构
逻辑地址A到物理地址E的过程,L页面大小
- 系统设置一个PTR(页表寄存器):存放起始地址F,页表长度M;
- 计算逻辑地址的页号P,页内偏移量W;【P=A/L】【W=A%L】
- 判断P>=M 则页号大小超出了所能表示的最大范围,越界中断,否则继续执行
- 页表中页号P对应的页表项地址 = 页表始址F+页号P*页表项长度
- 根据页表项的地址取出内存块号b
- E=b*L(页面大小)+W,就是逻辑地址对用的物理地址
两个问题
- 地址转换需要足够快,否则访存速度降低
- 每个进程引入页表,页表不能太大,否则内存的利用率降低(为进程实现额外的开销就是页表)
具有快表的地址变换机构
在地址变换机构中增加一个具有并行查找能力的高速缓冲器(快表)又叫做相连存储器TLB;用来存储当前访问的若干页表项,加速地址变化,对应内存的页表叫做慢表;【快表考虑的是增加快表命中率,基于局部性原理】
访存次数:没有快表2次(1,访问主存页表,取出页表项地址对应的内存块b,2:取出需要的内容),有快表,如果能命中:1次(少了页表查找)
多级页表
- 页表连续存储,页表很大时要占用很多连续的页框
- 整个页表都常驻内存,进程在一段时间neural只需要几个页面
- 用多级页表,只需要将顶级页表常驻内存就可以
- 多级页表机制,各级页表大小不能超过一个页面能存放最多的页表项大小
- 顶级页表应该只有一个最好
32为逻辑地址,页面4KB,页表项4
在上述的例子中如果不用多级页表,需要将10万个内存页框保存页表;现在一页4KB,一个页表项4B,一个页面存放1024个页表项,如果我们对这10万条页框也开进行划分,1024为一组只需要1024个页表,这个页表存放的就是我们用1024划分10万个页表的编号就可以表示这10万个页表框,图表难得画,后续再说吧
地址转换过程
- PCB读出目录表始址
- 在一级页表中查询一级页号(由逻辑地址得出页号)得到一个对应的内存块A,这个A存放的是二级页表对应【第一次访存】
- 在内存块A中查找二级页表的页号(由逻辑地址得出页号)对应的数据内存块B【第2次访存】
- 如果是多级页表是二级页表,在内存块B+偏移量就是E(逻辑地址对应的物理地址),否则持续3;【第3次访存】
两级页表访存次数:3次
分段存储管理(和分页有一点类似)
地址变换机构
区别与分页
- 页是信息的物理单位,少量内部碎片,段是逻辑单位,外部碎片
- 分页为了实现离散分配,提高内存利用率,是OS管理上的需要,由OS决定,对用户透明;分段 为了满足用户需求,由用户决定,对用户不透明
- 分段比分页更容易实现信息共享与保护,eg:分页:现在需要共享1页号后面2kb和2页号前面2kb的内容,这对分页很困难,对于分段只需要加个上下限就可以了
段页式
地址变换
- 通过段表查询页表始址,通过页表找到页框号,最后形成物理地址
- 判断越界,断号S与段表长度M,页号可能也会越界
- 3次访存:访问段表,访问页表,访问目标内存单元
- 段的位数决定了一个进程最多被划分为多少段
- 页的位数决定了每个段最多多少页
- 页内偏移量取决于 内存块(页面) 大小
- 段页式管理地址结构是二维的
- 段对用户是不透明的(由用户分段),页对用户是透明的(由OS决定)