现代操作系统:内存管理(一)
4 Memory Management内存管理
通常也称之为存储管理(storage management)或空间管理(space management)。
内存管理器必须处理现代计算机中的具有层次性的存储结构。该层次结构由寄存器(最高级别)、缓存、中央内存、磁盘组成。当我们移动到较低的层次时,内存变得更大但更慢。
各种(硬件和软件)内存管理器将数据从层次结构的一层移动到另一层。目标是将大/慢内存与小/快内存相结合,(几乎)达到大/快内存的效果。
202主要与中央存储器↔disk接口有关。
研究计算机体系结构时,高速缓存↔中央存储器接口也提出了我们对中央存储器接口要问的问题。令人惊讶的是,术语几乎完全不同!
- 我们应该在什么时候将数据移动到更高的层次?按需获取(按需求分页)和预获取(文件IO预读;软件或硬件预读取;大型缓存行和页;极端的案例:无论何时运行,整个任务都会呈现);
- 除非顶层有足够的内存供整个系统使用,否则我们还必须决定何时将数据向下移动到更低的层,这通常被称为逐出数据(evicting the data);
- 在操作系统课程中,我们更关注数据在中央内存和磁盘间的转换;
- 在计算机结构课程中,我们更关注数据在中央内存和缓存间的转换;
在未来的几周内我们将看到三个独立的内容:
- 我们需要分页吗?(Paging);
- 我们需要按需分页吗?(Demand Paging);
- 我们需要进一步细分段吗?(Segmentation);
Memory management implements address translation内存管理实现地址转换
- 将虚拟地址转换为物理地址:也成为逻辑地址到真实地址的转换;虚拟地址是进程中表示的地址;物理地址是被计算机硬件理解为实际内存中某个位置的地址;
- 从虚拟地址向物理地址的转换是由内存管理单元MMU执行的,地址转换的另一个例子是链接器将相对地址转为绝对地址;
- 从虚拟地址到物理地址的转换在现代操作系统之中是非常重要的;
- 从虚拟地址到物理地址的转换过程(翻译)可能会很困难:通常包括了一些addition、shift、mask操作;通常包括内存引用。非常严谨,解决方案是在翻译后备缓冲区中缓存翻译(Translation Lookaside Buffer TLB);
Homework 21
What is the difference between a physical address and a virtual address?
虚拟内存是每个进程运行所持有的内存,对每个进程而言它通常从0开始,不代表真正的物理内存位置;而物理内存是计算机硬件理解的实际内存中的某个位置,虚拟内存和物理内存存在映射关系。
When is address translation performed? 什么时候进行地址转换
程序首先被编写,然后被编译,然后链接,然后加载,最后被执行,地址的转换可能在其中的任何一个时间发生:
- 在编写程序时:A. 程序员明确的声明了所有东西的去向;B. 不再这样做了;
- 在程序编译时:A. 编译器生成物理地址;B. 需要知道编译单元在哪里加载;C. 没有链接器;D. 加载器是微不足道的;E. 非常原始;
- 在链接编辑时:A. 为每个编译单元生成相对(即可重定位)地址;B. 引用外部地址;C. 将相对地址转换为绝对地址;D. 解析外部引用;E. 还必须通过知道连接的程序在哪里加载来将虚拟地址转为物理地址;加载器仍然是微不足道的;对硬件要求小;程序只能加载到指定的位置,一旦加载就不能移动,不能将程序分割为多个部分;
- 在程序加载时:A. 类似于在链接编辑时,但是不固定起始地址;B. 程序可以在任何地方加载;C. 程序可以移动但是不能拆分;D. 需要适当的硬件作为支持;E. 加载器用于配置这些硬件;F. 但是已经不再常见了;
在程序执行时:A. 在执行过程中动态转换地址;B. 程序可以加载在任何地方并可以移动;C. 程序可以是分割成块(一般是固定大小的块);D. 快速执行虚拟到物理地址转换所需的硬件(MMU);E. 目前占据着主导地位。
Extensions
A. Dynamic Loading动态加载
- 当执行一个调用时,首先检查模块是否被加载;
- 如果它没有被加载,就让一个链接加载器加载它并更新数据表,用于存储当前这个模块已经被加载以及加载的位置;
- 这个过程会减慢对进程的所有调用,除非你动态的重写代码;
- 现在已经不常用了
B. Dynamic Linking动态链接:后续会讲,是常用的方法!
4.1 No Memory Management无内存管理
整个进程从开始到结束都保留在内存中,并且不能移动。因此,系统中所有作业的内存需求之和不能超过系统所持有的物理内存的大小。
Monoprogramming单道编程
几十年前的时候这些都很容易,但是现在emmm……
- OS不会执行地址转换(即地址转换在执行过程中不会动态执行);
- 为每个作业重新加载操作系统(或没有操作系统)或从作业中保护操作系统;当然必须给与操作系统一定的RAM空间;可以有一个单独的操作系统地址空间,但只能在内核态下访问;可能会在ROM(BIOS)中放入一些驱动程序;
- 如果作业所需的内存超过物理内存的大小,则会产生覆盖Overlay:程序员会将程序分解为几个模块;程序的根模块始终保存在内存中,其中存储了加载和卸载各种组件的调用;程序员的责任是确保一个子模块被加载后它被调用;但现在也已经不使用了,如果没有这玩意上世纪60年代不会登月成功。覆盖已经被动态地址翻译和其它特性所取代,这些新特性通常运行在支持虚拟地址大于物理地址的系统上。

因为最简单的内存管理就是不管理,不管理也就意味着当我们写程序的时候就直接操作物理内存,因此在这种情况下就不能同时运行多个进程,也就是单道程序设计。上面的三张图表明了几种曾经的存储结构和特性,第一种被应用于大型机和小型计算机上;第二种被应用于一些嵌入式系统和掌上电脑中;第三种被应用于早期的个人计算机中。但是将操作系统放置于RAM中的一个问题就是当用户的进程出现错误时很有可能直接摧毁操作系统。
Running Multiple Programs Without a Memory Abstraction不使用内存抽象运行多个进程
如果我们一次只加载一个程序,那么就可以通过Swap交换来完成,即如果运行多个进程时我们可以将当前正在运行的进程的所有内存保存在磁盘中,然后加载新的进程进入内存,等新的进程处理完毕后再从磁盘中恢复之前被暂时保存的那个进程。
它还可以支持一种有限形式的多道编程,类似于MFT(后面将介绍)。在这个有限的版本中,加载程序通过添加加载程序的地址来重定位所有的相对地址。这允许多个进程在物理内存中共存,就像链接器允许多个模块在单个进程中共存一样。(也就是类比到那个第0章提到的迁移常数)

**Multiprogramming with Fixed Partitions固定分区的多道程序设计
多道编程的两个目标是通过重叠CPU和I/O来提高CPU利用率,以及允许短的任务快速完成。该方案被IBM用于360 OS/MFT(Multiprogramming with a fixed number of tasks)系统。
- 你可以把输入列表想象成就绪态的进程列表,每一个分区都有一个从运行到完成的调度策略;
- 每个分区都是单道的,多道程序设计是通过跨分区进行的;
- 分区的边界不能移动,那么必须重启后才能移动作业,所以分区的大小是固定的;
- MFT系统中可能会有很大的内部内存碎片,即分配给进程的内存区域存在冗余;
- 每一个进程有一个单独的段(但是每个进程的内存空间是连续的,无共享内存);
- 没有动态地址转换,os/MFT是加载期间实现地址转换的一个实例;
posted on 2022-01-06 15:35 ThomasZhong 阅读(470) 评论(0) 收藏 举报
浙公网安备 33010602011771号