1.内存的基础知识
内存可存放数据。程序执行前需要先放到内存中才能被CPU处理——缓和CPU与硬盘之间的速度矛盾
1.1指令的工作原理
1.2编辑、编译、链接、装入
1.3三种链接方式
(1)静态链接:在程序运行之前, 先将各目标模块及它们所需的库函数连接成一个完整的可执行文件(装入模块), 之后不再拆开。
(2)装入时动态链接:将各目标 模块装入内存时,边装入边 链接的链接方式。 (不会一开始就链接,只有放入内存时开始链接)
(3)运行时动态链接:在程序执 行中需要该目标模块时,才对它进行链接。其优点是便于修改和更新,便于实现对目标模块的共享。 (用不到的模块不需要装入内存)
1.4装入的三种方式
1.4.1绝对装入
缺点:绝对装入只适用于单道程序环境。灵活性较差。
1.4.2可重定位装入
缺点:在一个作业装入内存时,必须分配其要求的全部内存空间,如果没有足够的内存,就不能装入该作业。 作业一旦进入内存后,在运行期间就不能再移动,也不能再申请内存空间。
1.4.3动态重定位(现代常用)
条件:这种方式需要一个重定位寄存器的支持
2.内存管理的概念
2.1内存保护
为了使进程只能在对应的内存中的位置进行工作,不会越界访问。
内存保护可采取两种方法:
2.2总体知识
2.3进程的内存映象
堆的数据(也就是malloc分配的),取决于读/写数据、只读代码/数据和未使用区,将分别的1GB减去这些区占用的空间,也就是堆可分配的空间。
用户栈包含着调用函数等信息。
#define不专门分配存储空间,在预编译阶段,会将代码中的X替换成1024(联系回忆计组的立即数相关知识点)。
3.覆盖与交换
3.1覆盖技术
方法:按照自身逻辑结构,让那些不可能同时被访问的程序段共享同一个覆盖区
特点:由于程序中的调用结构,操作系统是不知道的,所以必须由程序员声明覆盖结构,操作系统完成自动覆盖。
固定区中的程序段在运行中不会调入调出。
覆盖区中的程序段在运行过程中会根据需要调入调出。
缺点:对用户不透明,增加了用户编程负担。 覆盖技术只用于早期的操作系统中,现在已成为历史。
3.2交换技术
交换(对换)技术的设计思想:内存空间紧张时,系统将内存中某些进程暂时换出外存,把外存中 某些已具备运行条件的进程换入内存(进程在内存与磁盘间动态调度)
也就是之前说的,高级调度、中级调度、低级调度里面的中级调度(内存调度),就是要决定将哪个处于挂起状态的进程重新调入内存。
暂时换出外存等待的进程状态为挂起状态(挂起态,suspend)
挂起态又可以进一步细分为就绪挂起、阻塞挂起两种状态
从而形成“七状态模型”
三个问题
1. 应该在外存(磁盘)的什么位置保存被换出的进程?
2. 什么时候应该交换?
3. 应该换出哪些进程?
1. 具有对换功能的操作系统中,通常把磁盘空间分为文件区和对换区两部分。文件区主要用于存放文件,主要追求存储空间的利用率,因此对文件区空间的管理采用离散分配方式;对换区空间只占磁盘空间的小部分,被换出的进程数据就存放 在对换区。由于对换的速度直接影响到系统的整体速度,因此对换区空间的管理主要追求换入换出速度,因此通常对换区采用连续分配方式(学过文件管理章节后即可理解)。总之,对换区的I/O速度比文件区的更快。(也就是应该在对换区进行换入和换出)
2. 交换通常在许多进程运行且内存吃紧时进行,而系统负荷降低就暂停。例如:在发现许多进程运行时经常发生缺页,就说明内存紧张,此时可以换出一些进程; 如果缺页率明显下降,就可以暂停换出。->涉及之后的缺页和缺页率相关的知识点。
3. 可优先换出阻塞进程;可换出优先级低的进程;为了防止优先级低的进程在被调入内存后很快又被换出(就会出现饥饿现象),有的系统还会考虑进程在内存的驻留时间…
(注意:PCB 会常驻内存,不会被换出外存):换出内存不是讲文件所有数据进行换出,需要对数据名称标明和保留信息这些(PCB)不会换出外存。
3.3覆盖和交换的区别
覆盖是在同一程序或进程中的
交换是在不同进程(或作业中)进行的
4.内存空间的分配与回收-连续分配管理方式
区别是:连续分配,内存分配的一定是连续的空间,而非连续的分配空间不一定是连续的,可以是离散的。
4.1单一连续分配方式
特点:内存中只能有一道用户程序,用户程序独占整个用户区空间。
优点:实现简单;无外部碎片;可以采用覆盖技术扩充内存;不一定需要采取内存保护(eg:早期的 PC 操作系统MS-DOS)。
缺点:只能用于单用户、单任务的操作系统中;有内部碎片;存储器利用率极低。
分配给某进程的内存区域 中,如果有些部分没有用上,就是“内部碎片”
4.1.2固定分区分配
在内 存中装入多道程序,且这些程序之间又不会相互干扰, 于是将整个用户空间划分为若干个固定大小的分区,在每个分区中只装入一道作业
类别:分区大小相等和分区大小不等
分区大小相等:缺乏灵活性,但是很适合用于用一台计算机控制多个相同对象的场合(钢铁厂有n个相同的炼钢炉,就可把内存分为n个大小相等的区域存放n个炼钢炉控制程序)
分区大小不等:增加了灵活性,可以满足不同大小的进程需求。根据常在系统中运行的作业大小情况进行划分 (比如:划分多个小分区、适量中等分区、少量大分区)
分区大小不等:
优点:实现简单,无外部碎片。
缺点:a. 当用户程序太大时,可能所有的分区都不能满足需求,此时不得不采用覆盖技术来解决,但这又会降低性能;b. 会产生内部碎片,内存利用率低。
4.2动态分配
无内部碎片,有外部碎片。
1. 系统要用什么样的数据结构记录内存的使用情况?
2. 当很多个空闲分区都能满足需求时,应该选择哪个分区进行分配?
3. 如何进行分区的分配与回收操作? 假设系统采用的数据结构是“空闲分区表”...如何分配?
当空闲分区的大小与此处所需分配的大小相同时
需要把对应的分区的表项删除
3. 如何进行分区的分配与回收操作? 假设系统采用的数据结构是“空闲分区表”...如何分配?
情况二:回收区的前面有一个相邻的空闲分区->与上面的情况很类似。
情况三:回收区的前、后各有一个相邻的空闲分区
三个空闲分区变为两个空闲分区
情况四:回收区的前、后都没有相邻的空闲分区
总结:四种情况,可以用一句话概括。在回收之后,发现有一些内存空间是相邻的,就需要把相邻的空间进行合并。
内部碎片,分配给某进程的内存区域中,如果有些部分没有用上。
外部碎片,是指内存中的某些空闲分区由于太小而难以利用。
可以通过紧凑(拼凑,Compaction)技术来解决外部碎片。
4.3动态分区分配算法
动态分区分配算法:在动态分区分配方式中, 当很多个空闲分区都能满足需求时,应该选择哪个 分区进行分配?
4.3.1首次适应
4.3.2最佳适应
算法思想:由于动态分区分配是一种连续分配方式,为各进程分配的空间必须是连续的一整片区 域。因此为了保证当“大进程”到来时能有连续的大片空间,可以尽可能多地留下大片的空闲区, 即,优先使用更小的空闲区。
方法:空闲分区按容量递增次序链接。每次分配内存时顺序查找空闲分区链(或空闲分区 表),找到大小能满足要求的第一个空闲分区。
缺点:每次都选最小的分区进行分配,会留下越来越多的、很小的、难以利用的内存块。因此这种方法会产生很多的外部碎片。
4.3.3最坏适应算法
算法思想:为了解决最佳适应算法的问题——即留下太多难以利用的小碎片,可以在每次分配时 优先使用最大的连续空闲区,这样分配后剩余的空闲区就不会太小,更方便使用。
方法:空闲分区按容量递减次序链接。每次分配内存时顺序查找空闲分区链(或空闲分区 表),找到大小能满足要求的第一个空闲分区。
缺点:每次都选最大的分区进行分配,虽然可以让分配后留下的空闲区更大,更可用,但是这种方式会导致较大的连续空闲区被 迅速用完。如果之后有“大进程”到达,就没有内存分区可用了。
4.3.4邻近适应算法
总结:
综合来看:反而首次适应算法的效果是最好的。
最佳适应和最坏适应可能要多次进行进行排序。
5.内部空间的分配与回收-非连续分配管理方式
5.1基本分页存储管理
5.1.1分页存储
页框:将内部空间一个一个大小相等,每一个分区就是一个“页框”(页框=页桢=内存块=物理块=物理页面)
页框号:每一个页框有一个编号,即“页框号”(页框号=页桢号=内存块号=物理块号=物理页号),页框号从0开始。
5.1.2每个页表项占多少字节
大题出现必要算:
页号是不需要占储存空间的,页表项连续存放,因此页号可以是隐含的,不占存储空间(类比数组)
5.1.3地址的转换
5.1.4逻辑地址结构
5.1.5基本地址变换机构
基本分段存储管理
这个不够直观:直接看咸鱼骚图理解。
5.2具有快表的地址变换机构
直接看咸鱼的骚图更好理解。
计算:分步查找和同时查找
5.3两级页表
为解决单级页表的问题。
问题一:页表必须连续存放,因此当页表很大时,需要占用很多个连续的页框。
若采用多级页表机制,除一级页表的各级页表的大小不能超过一个页面。
问题二:没有必要让整个页表常驻内存,因为进程在一段时间内可能只需要访问某几个特定的页面。
可以在需要访问页面时才把页面调入内存(虚拟存储技术)。可以在页表项中增加一个标志位,用于表示该页面是否已经调入内存。
6.基本分段存储管理方式
6.1分段
分配规则:以段为单位进行分配,每个段在内存中占据连续空间,但各段之间可以不相邻。
优点:由于是按逻辑功能模块划分,用户编程更方便。
编译程序会把段名转换为段号
段号的位数决定了每个进程最多可以分几个段
6.2段表
程序分多个段,各段离散地装入内存,为了保证程序能正常运行,就必须能从物理内存中 找到各个逻辑段的存放位置。为此,需为每个进程建立一张段映射表,简称“段表”。
段表的作用和之前讲的页表的作用是类似的。相对于页表,段表多了一个段长。
- 每个段对应一个段表项,其中记录该段在内存中的起始位置(又称基址)和段的长度。而页表项中记录的是块号,并且不记录段的长度。
- 各个段表项的长度是相同的。
- 段号是隐含的,不占存储空间。
6.3地址变换
段表寄存器:用于存放所需进程在寄存器的段表始址F和段表长度M
注意:段表长度至少是1,而段号是从0开始的
6.4分段、分页管理的对比
- 页是信息的物理单位。分页的主要目的是为了实现离散分配,提高内存利用率。分页仅仅是系统管理上的需要,完全是系统行为,对用户是不可见的。
- 段是信息的逻辑单位。分段的主要目的是更好地满足用户需求。一个段通常包含着一组属于一个逻 辑模块的信息。分段对用户是可见的,用户编程时需要显式地给出段名。
- 页的大小固定且由系统决定。段的长度却不固定,决定于用户编写的程序。
- 分页的用户进程地址空间是一维的,程序员只需给出一个记忆符即可表示一个地址。
- 分段的用户进程地址空间是二维的,程序员在标识一个地址时,既要给出段名,也要给出段内地址。
分段比分页更容易实现信息的共享和保护。
方法:只需让各进程的段表 项指向同一个段即可实现共享。
分页(单级页表):第一次访存——查内存中的页表,第二次访存——访问目标内存单元。总共两次访存
分段:第一次访存——查内存中的段表,第二次访存——访问目标内存单元。总共两次访存。
7.段页式管理方式
7.1分页、分段的优缺点分析
7.2段页式管理
7.3段页式管理的逻辑地址结构
- 段号的位数决定了每个进程最多可以分几个段
- 页号位数决定了每个段最大有多少页
- 页内偏移量决定了页面大小、内存块大小是多少
注意这里的段表和段式管理方式的段表的不同。
第一次访存,查段表;第二次访存,查页表;第三次访存,访问目标内存单元。
8.三种离散分配方式对比
页是信息的物理单位,对用户是不可见的。
段是信息的逻辑单位,对用户是可见的。
在不引入快表和多级页表时:
分页二次访存,分段二次访存,段页式三次访存。