内存管理 操作系统笔记整理系列
Posted 雨宙
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内存管理 操作系统笔记整理系列相关的知识,希望对你有一定的参考价值。
内存管理
冯诺依曼体系中的存储:
主存:只有CPU可以直接访问的大型存储介质
二级存储:主存的扩展,提供大的非易失的存储容量,比如磁盘
存储结构:
存储系统通常根据其速度、成本和波动性进行分层组织
存储层次结构之间的移动可以是显式的,也可以是隐式的
背景
- 内存由一个很大的字节数组组成,每个字节都有自己的地址。
(1)CPU根据程序计数器的值从内存中获取指令。
(2)这些指令可能导致额外的加载和存储(存储到特定的内存地址)。 - 程序运行必须先加载到内存中(程序被放置在进程中)。
- 输入队列:磁盘上等待被放入内存运行程序的进程的集合。
- 每个进程都有分离的内存空间,其实现需要基地址寄存器(Base register)和界限地址寄存器(Limit register)
- CPU访问一个地址,需要判断是否大于基地址,是否小于基地址+界限地址。
地址绑定
- 通常,地址绑定可以发生在编译阶段、加载阶段和运行阶段。
(1)编译阶段:如果在编译时就已知道进程将在内存中的驻留地址,那么就可以生成绝对地址。(适用于单道程序环境)
(2)加载阶段:如果在编译时并不知道进程将驻留在何处,那么编译器就应生成可重定位地址,对这种情况,最后绑定会延迟到加载时才进行,
(3)执行阶段:如果进程在执行时可以从一个内存段移到另一个内存段,那么绑定应延迟到执行时才进行。(最优)
逻辑地址和物理地址
- 逻辑地址:由CPU生成,也可以称为虚拟地址。
- 物理地址:内存单元中的实际地址。
- 编译时和加载时的地址绑定方法生成相同的逻辑地址和物理地址,执行时的地址绑定方案生成不同的逻辑地址和物理地址。
内存管理单元(MMU)
- 是一个硬件设备,将虚拟地址转换为物理地址。
- 在MMU方案中,重定位寄存器(又称基地址寄存器)中的值在被发送到内存时被添加到用户进程产生的每个地址中,即用户进程所生成的地址在送交内存之前,都将加上重定位寄存器的值。
动态加载
- 进程的大小受物理内存大小的限制,为了获得更好的内存空间利用率,使用动态加载。
- 采用动态加载时,一个程序只有在调用时才会加载,所有程序都以可重定位加载格式保存在磁盘上。
- 动态加载的优点是,只有一个程序被需要时,它才会被加载,当大多数代码用来处理异常情况时,这种方法很有用。
- 动态加载不需要操作系统提供特别支持。
动态链接
- 存根:是一小段代码,用来指出如何定位适当的内存驻留库程序,或者在程序不在内存时应如何加载库。
- 动态链接需要操作系统的支持,需要操作系统检查所需程序是否在某个进程的内存空间内。
覆盖
- 在内存中只保存那些在给定的时间需要的指令和数据。
交换(Swapping)
- 可以将进程暂时从内存中交换到后备存储器,然后将其带回内存继续执行。
- 交换策略被用于基于优先级的调度算法,如果高优先级的进程到达并需要服务,内存管理器可以换出低优先级的进程,以加载和执行高优先级的进程。
连续分配(Contiguous Allocation)
主存被分为两部分,操作系统与中断向量保存在低内存中,用户进程保存在高内存中。
- 在连续内存分配中,每个进程都被包含在一个单独的连续内存中。
内存保护
- 如何保护操作系统免受用户进程的影响,以及保护用户进程不受其他用户进程的影响
(1)使用重定位寄存器,包含最小物理地址的值
(2)使用界限地址寄存器,包含逻辑地址范围
(3)每个逻辑地址必须小于界限地址寄存器
(4)内存管理单元MMU通过在重定位寄存器添加值来动态映射逻辑地址(逻辑地址+基地址) - CPU产生逻辑地址,需先与界限地址寄存器进行比较,若小于界限地址寄存器则加上重定位寄存器中的基地址,来获得物理地址。
内存分配
- 可变分区分配
(1)孔:可用的内存快,不同大小的孔分散在整个内存中
(2)当一个进程需要被分配内存空间时,从一个足够大的孔中分配内存来容纳这个进程
(3)操作系统维护已分配的分区信息和空闲分区信息 - 动态分配问题——如何从一组空闲的孔中满足一个大小为N的请求
(1)首次适应:分配第一个足够大的孔
(2)最佳适应:分配最小的足够大的孔
(3)最差适应:分配最大的孔
(4)在速度和存储利用率方面,首次适应和最佳适应优于最差适应 - 碎片
(1)外部碎片:进程外部无法分配给进程的空间
(2)内部碎片:已经分配给进程,但是进程不能使用(进程所分配的内存可能比所需的要大)
(3)通过紧缩(compaction)来减少外部碎片:将所有空闲内存放在一个大块中。(只有重定位是动态地,并且在运行时进行的,才可以采用紧缩)
分页(Paging)
分页允许进程的物理地址空间是非连续的
- 将物理内存分为固定大小的块,称为帧
- 将逻辑内存分为固定大小的块,称为页
地址转换方案
- CPU产生的地址被分为页码和页偏移
- 页码作为页表的索引(页表包含每页所在的物理内存的基地址,可以通过页码查物理内存基地址,基地址与页偏移的组合形成了物理内存地址)
- 如果逻辑地址空间为2m,且页大小为2n,则逻辑地址的高m-n位表示页码,低n位表示页偏移
碎片问题
- 使用分页方案,没有外部碎片,但可能有内部碎片
页大小
- 页大小通常在4KB到8KB之间,也有系统支持更大的页
- 通常,对于32位的CPU,每个页表条目是4字节长的,可以指向232个物理帧,但是这个大小也有可能改变
分页特征
分页的一个重要方面是,程序员视图的内存和实际的物理内存清楚分离
页表的实现
- 页表小,保存在寄存器中
- 页表大,被保存在主存中,此时页表基寄存器(PTBR)指向页表,页表长度寄存器(PTLR)表示页表的大小,在这种方案中,每次数据/指令访问都需要两次内存访问,一个用于页表,一个用于数据或指令
- TLB(转换表缓冲区):可以加入新的硬件TLB,关联内存,TLB只包含少量的页表条目,当CPU产生一个逻辑地址后,它的页码发送到TLB,如果找到可用于访问内存,如果没找到就需访问页表,再将页码和帧码添加到TLB
- 有效访问时间(注意,需要加入访问数据/指令所需的时间,即不管如何都加上一次访问内存的时间)
内存保护
- 附在页表中每个条目上的有效-无效位
- 当该位为有效时,该值表示相关的页在进程的逻辑地址空间内,在内存中
- 当该位为无效时,该值表示相关的页不在进程的逻辑地址空间内,可能在磁盘中
页表结构
- 分层页表:页表、页表的页表……
- 哈希页表(虚拟页码被散列到一个页表中)
- 反向页表(进程是通过虚拟地址来引用页,操作系统可以将这种引用转换成物理内存的地址)
共享页
- 共享代码:进程间共享只读代码的一个副本
- 私有代码和数据:
(1)每个进程都保留一份寄存器和数据的单独副本。
(2)私有代码和数据的页面可以出现在逻辑地址空间的任何地方。
分段(Segmentation)
- 进程的地址空间:按照程序自身逻辑关系划分为若干个段,每个段都有一个段名,每段从0开始编址。
- 内存的分配规则:以段为单位进行分配,每个段在内存中占据连续空间,但各段之间可以不相邻。
- 分段系统的逻辑地址结构由段号(段名)和段内地址(段内偏移量)所组成。
- 段号的位数决定每个进程最多可以分几个段,段内地址位数决定每个段的最大长度是多少。
- 段表:将二维的逻辑地址映射为一维的物理地址。包括段在内存中的起始物理地址和段的长度。
分页式分段(Segmentation with Paging)
以上是关于内存管理 操作系统笔记整理系列的主要内容,如果未能解决你的问题,请参考以下文章