操作系统概念笔记——第八章:内存管理
Posted 叶卡捷琳堡
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了操作系统概念笔记——第八章:内存管理相关的知识,希望对你有一定的参考价值。
文章目录
第八章:内存管理
本章目标:
- 提供组织存储器硬件的各种方法的详细描述
- 讨论各种内存管理技术,包括分页和分段
所以,之后要介绍的分页和分段,都是基于内存的管理技术,是为了管理内存
8.1 背景
内存是现代计算机运行的中心。CPU根据程序计数器PC的值从内存中提取指令,这些指令可能会引起进一步对特定内存地址的读取和写入
8.1.1 基本硬件
- CPU所能直接访问的存储器只有内存和处理器内的寄存器
- 机器指令可以用内存地址作为参数,而不能用磁盘地址作为参数。因此,执行指令以及指令使用的数据必须从磁盘转移到内存中
- CPU内置寄存器通常可以在一个CPU时钟周期内完成访问,但完成内存的访问可能需要多个CPU时钟周期
- 如果内存被频繁访问,这种情况不好,因此需要在CPU和内存中增加高速缓存
基地址和界限地址寄存器
为了确保每个进程都有独立的内存空间,需要确保进程可访问的合法地址的范围,并确保进程只访问其合法地址
基地址寄存器含有最小的合法物理内存地址,界限地址寄存器决定了范围的大小
内存空间保护的实现,是通过CPU硬件对用户模式所产生的每一个地址与寄存器的地址进行比较来完成的。
如果在用户模式下执行的程序试图越过界限,访问其它部分的内存,则会陷入到操作系统,并作为致命错误处理
只有操作系统可以通过特殊的特权指令来修改和加载基地址寄存器和界限地址寄存器
8.1.2 地址绑定
程序以二进制可执行文件的形式存储在磁盘上。为了执行,程序被调入内存并放在进程空间内。
在磁盘等待调入内存以便执行的进程形成输入队列
许多系统允许用户进程放在物理内存的任意位置。而从磁盘调入内存的过程中需要地址绑定的过程
虽然现代计算机的地址空间从00000开始,但是用户进程的开始地址不一定是00000。用户程序执行之前,需要经过好几个步骤,其中有的步骤是可选的,这些步骤中,地址可能有不同的表示形式,源程序中的地址通常是用符号来表示的。
编译器常常将这些符号地址绑定在可重定位的地址
将指令与数据绑定到内存地址有以下几种情况
- 编译时:如果在编译时就知道进程将在内存中的驻留地址,那么就可生成绝对代码
- 加载时:如果在编译时不知道进程将在内存中的驻留地址,那么编译器就必须生成可重定位代码
- 执行时:如果进程执行时可以从一个内存段转移到另一个内存段,那么绑定必须延迟到执行时才能执行
8.1.3 逻辑地址空间和物理地址空间
CPU所生成的地址通常称为逻辑地址,而内存单元所看到的地址(加载到内存地址寄存器中的地址)通常称为物理地址
编译和加载时的地址绑定方法生成相同的逻辑地址和物理地址,但是,执行时的地址绑定方案将导致不同的逻辑地址和物理地址
通常称逻辑地址为虚拟地址,本书中逻辑地址 = 虚拟地址
运行时从虚拟地址到物理地址的映射是由**内存管理单元(MMU)**这个部件完成的
这种映射方法是对基地址寄存器方案的推广,基地址寄存器在这里被称为重定位寄存器
用户进程所生成的地址在送交内存之前,都将加上重定位寄存器的值
8.2 交换
这一部分内容老师说会和第9章的内容结合起来讲,暂时跳过了
8.3 连续内存分配
内存通常分为两个区域,一个用于驻留操作系统,另一个用于用户进程
通常需要将多个进程同时放在内存中,因此需要考虑如何为输入队列中需要调入内存的进程分配内存空间。采用连续内存分配时,每个进程位于一个连续的内存区域
8.3.1 内存映射与保护
采用重定向寄存器和界限地址寄存器可以实现对内存的保护
重定向寄存器含有最小的物理地址值,界限地址寄存器含有逻辑地址的范围值
8.3.3 碎片
外部碎片问题:随着进程装入和移出内存,空闲内存空间被分为小片段。当总的可用内存之和可以满足请求,但并不连续时,就出现了外部碎片问题。这个问题可能导致内存浪费
解决外部碎片问题的方法
- 紧缩:紧缩的目的是移动内存内容,以便使所有空余的内存空间合成一块。但有时候由于种种原因,紧缩无法进行。最简单的合并方法是将所有进程移到内存一端,然后将所有的孔移到内存的另一端
- 允许物理地址空间为非连续,这样只要有物理内存就可以分配
8.4 分页
分页内存管理方案允许进程的物理地址空间可以是非连续的
8.4.1 基本方法
在分页这种方法中,将物理内存分为固定大小的块,称为帧
同时将逻辑内存也分为同样大小的块,称为页
当需要执行进程时,页从备份存储中调入到可用的内存帧中
CPU生成的地址分为两个部分:页号(p)和页偏移(d)
页号作为页表中的索引,页表包含每页所在物理内存的基地址,这些基地址与页偏移的组合形成了物理地址
页大小通常由硬件决定,页的大小通常为2的幂
如果逻辑地址的空间为2^m
页的大小为2^n单元
则逻辑地址的高m-n位表示页号,低n位表示页偏移
关于逻辑内存映射到物理内存的过程,书上有,要求完全掌握
当系统进程需要执行时,它将检查该进程的大小(按页计算),进程的每页都需要一帧
分页的一个重要特点是实现用户视角的内存和实际的物理内存的分离。用户程序将内存作为一整块来处理,只包括这一个进程。
事实上,一个用户程序与其它程序一起,分布在物理内存上。用户视角的内存和实际的物理内存的差异是通过地址转换硬件协调的,将逻辑地址转换为物理地址。这种转换受操作系统控制
8.4.2 硬件支持
绝大多数操作系统都为每个进程分配一个页表。
页表的硬件实现由多种方法
- 把页表作为一组专用寄存器来实现(适用于页表较小的情况)
- 由于在多数情况下页表较大,因此需要将页表放在内存中,并将页表基寄存器(PTBR)指向页表。改变页表只需要改变这一寄存器
采用第二种方法会导致一个问题,一个字节需要两次访存才能取出(一次用于找页表条目,一次用于字节)
为了解决这个问题,使用了一种快速硬件缓冲,这种缓冲称为转换表缓冲区(TLB)。TLB是关联的快速内存。
TLB由键值对组成。采用这种方式可以快速访问页表(和Cache类似)
页号在TLB中被查找到的百分比被称为命中率
8.4.3 保护
在分页环境下,内存保护是通过每个帧相关联的保护位来实现的。这些保护位存储在页表中
在页表中,会定义一个位,用来指定该页是可读写的还是只读的
这个位被称为有效-无效位(valid-invalid)
当该位为有效时,表示相关的页在进程的逻辑地址空间内。
当该位为无效时,表示相关的页不在进程的逻辑地址空间里
可以通过使用有效-无效位捕捉到非法地址
8.4.4 共享页
分页的优点之一在于可以共享公共代码,可以实现重用代码
下面这个图清晰地演示了分页环境下的代码共享
8.5 页表结构
8.5.1 层次页表
在现代计算机系统里,页表往往非常大,不可能在内存中分配这么大的一个连续空间用来存储页表。
一个简单的方法是将页表划分为更小的部分。
两级分页法
以4KB页大小的32位系统为例,一个逻辑地址被分为20位的页码和12位的页偏移。因为要对页表再分页,所以该页号可以分为10位的页码和10位的页偏移
p1是用来访问外部页表的索引,p2是外部页表的页偏移
这种方案也被称为向前映射页表
8.5.2 哈希页表
哈希页表常被用于处理超32位的地址空间,并以虚拟页码作为哈希值
哈希页表的每一条目都包括一个链表的元素,这些元素的哈希值相同
每个链表元素有三个域
- 虚拟页码
- 所映射的帧号
- 指向链表中下一个元素的指针
从这张图上可以看到,哈希表实际上使用的数组+链表组合的形式用于存储相应的页
8.5.3 反向页表
这部分内容不是重点,期末再来整理
8.6 分段
采用分页的方法会导致用户视角地内存和实际物理内存的分离。
用户视角的内存需要映射到实际物理内存,该映射允许区分逻辑内存和物理内存
8.6.1 基本方法
通常情况下,我们会将内存看作一组不同长度的段的集合,这些段之间并没有一定的顺序
8.6.2 硬件
实际地址映射是通过段表实现的。
段表的每个条目都有段基地址和段界限,段基地址包含该段在内存中的开始物理地址,而段界限指定该段的长度
关于段的硬件原理,具体看这张图
具体的例子可以看这张图
以上是关于操作系统概念笔记——第八章:内存管理的主要内容,如果未能解决你的问题,请参考以下文章