操作系统-王道老师
第三章-内存
目录:
1.内存的基础知识
1.1 什么是内存,有何作用
1.2 进程运行的基本原理
2.内存管理的概念
2.1 内存空间的分配与回收
2.2 内存空间的扩充
2.3 地址转换
2.4 存储保护
3.覆盖和交换
3.1 覆盖技术
3.2 交换技术
3.3 覆盖和交换的区别
4.连续分配管理方式
4.1 单一连续分配
4.2 固定分区分配
4.3 动态分区分配
5.动态分区分配算法
5.1 首次适应算法
5.2 最佳适应算法
5.3 最坏适应算法
5.4 邻近适应算法
5.5 四者对比
1.内存的基础知识
1.1 什么是内存,有何作用
1.1.1 基本概念:
内存就是用于存储数据的硬件,程序执行前需要先放到内存中才能被CUP处理。
1.1.2 其他概念:
内存地址从0开始,每一个地址对应一个存储单元
存储单元: 内存中也有一个一个的“小房间”,每个小房间就是一个“存储单元”。
如果计算机“按字节编址”,则每个存储单元大小为1字节,即1B,即8个二进制位(bit),
如果字长为16位的计算机"按字编制",则每个存储单元的大小为1个字,每个字的大小为16个二进制位。
具体的“存储单元”的大小需根据具体计算机而定。
1.1.3 几个常用的数量单位:
2^10 = 1K (千)
2^20 = 1M (兆,百万)
2^30 = 1G (十亿,千兆)
1.2 进程运行的基本原理
1.2.1 相对地址和逻辑地址:
1.可见,我们写的代码要翻译成CPU能识别的指令。这些指令会告诉CpU应该去内存的哪个地址存/取数据,这个数据应该做什么样的处理。在这个例子中,指令中直接给出了变量x的实际存放地址**(物理地址)但实际在生成机器指令的时候并不知道该进程的数据会被放到什么位置。所以编译生成的指令中一般是使用逻辑地址(相对地址)。
2.相对地址由称为逻辑地址**,绝对地址又称物理地址。
1.2.2 从写程序到程序运行:
编译: 由编译程序将用户源代码编译成若干个目标模块(编译就是把高级语言翻译为机器语言)。
链接: 由链接程序将编译后形成的一组目标模块,以及所需库函数链接在一起,形成一个完整的装入模块。
装入(装载): 由装入程序将装入模块装入内存运行。
1.2.3 三种链接方式:
静态链接:
在程序运行之前,先将各目标模块及它们所需的库函数连接成。
装入时动态链接:
将各目标模块装入内存时,边装入边链接的链接方式。
运行时状态链接:
在程序执行中需要该目标模块时,才对它进行链接。其优点是便于修改和更新,便于实现对目标模块的共享。
1.2.4 三种装入方式:
绝对装入:
在编译时,如果知道程序将放到内存中的哪个位置,编译程序将产生绝对地址的目标代码。装入程序按照装入模块中的地址,将程序和数据装入内存
静态重定位:
1.又称可重定位装入。编译、链接后的装入模块的地址都是从0开始的,指令中使用的地址、数据存放的地址都是相对于起始地址而言的逻辑地址。可根据内存的当前情况,将装入模块装入到到内存的适当位置。装入时对地址进行 “重定位”,将逻辑地址变换为物理地址(地址变换是在装入一次完成的)。
2.静态重定位的特点是在一个作业装入内存时,必须分配其要求的全部内存空间,如果没有足够的内存,就不能装入该作业。作业一旦进入内存后,在运行期间就不能再移动,也不能再申请内存空间。
动态运行装入:
又称动态运行时裝入。编译、链接后的装入模块的地址都是从0开始的。装入程序把裝入模块装入内存后,并不会立即把逻辑地址转换为物理地址,而是把地址转换推迟到程序真正要执行时才进行。因此装入内存后所有的地址依然是逻辑地址。这种方式需要一个重定位寄存器的支持。
2.内存管理的概念
2.1 内存空间的分配与回收
操作系统负责内存空间的分配和回收。
2.2 内存空间的扩充
操作系统需要提供某种即使从逻辑上对内存空间进行扩充。
2.3 地址转换
操作系统需要提供地址转换功能,负责程序的逻辑地址与物理地址的转换。
2.4 存储保护
方法一:
在CPU中设置一对上、下限寄存器,存放进程的上、下限地址。进程指令要访问某个地址时,CPU会见检查是否越界。
方法二:
采用重定位寄存器(又称基址寄存器)和界地址寄存器(又称限长寄存器)进行越界检查。重定位寄存器中存放的是进程的起始物理地址。界地址寄存器中存放的是进程的最大逻辑地址。
3.覆盖和交换
3.1 覆盖技术
覆盖技术的思想:
1.将程序分为多个段(多个模块) 常用的段常驻内存,不常用的段在需要时调入内存。
2.内存中分为一个“固定区”和若干个“覆盖区”。
3.需要常驻内存的段放在“固定区”中,调入后就不再调出(除非运行结束)。
4.不常用的段放在“覆盖区",需要用到时调入内存,用不到时调出内存。
缺点:
对用户不透明,增加用户编程负担。覆盖技术只用于早期的操作系统中,现在已成为历史。
3.2 交换技术
交换(对换)技术的设计思想:
内存空间紧张时,系统将内存中某些进程暂时换出外存,把外存中某些已具备运行条件的进程换入内存(进程在内存与磁盘间动态调度)。中级调度(内存调度),就是决定哪个处于“挂起态”的进程进入内存。
3.3 覆盖和交换的区别
覆盖 是在同一个程序或者进程中的。
交换 是不同进程(作业)之间的。
4.连续分配管理方式
4.1 单一连续分配
基本概念:
在单一连续分配方式中,内存被分为系统区和用户区系统区通常位于内存的低地址部分,用于存放操作系统相关数据,用户区用于存放用户进程相关数据。内存中只能有一道用户程序,用户程序独占整个用户区空间。
优点:
实现简单,无外部碎片,可以采用覆盖技术扩充内存,不一定需要采取内存保护(早期的PC操作系统 MS-DOS)
缺点:
只能用于单用户、单任务的操作系统中,有内部碎片,存储器利用率极低。
4.2 固定分区分配
基本概念:
20世纪60年代出现了支持多道程序的系统,为了能在内存中装入多道程序,且这些程序之间又不会相互干扰于是将整个用户空间划分为若干个固定大小的分区,在每个分区中只装入一道作业,这样就形成了最早的、最简单的一种可运行多道程序的内存管理方式。
分区大小相等:
缺乏灵活性,但是很适合用于用一台计算机控制多个相同对象的场合。(比如:钢铁厂有n个相同的炼钢炉,就可把内存分为n个大小相等的区域存放n个炼钢炉控制程序)。
分区大小不相等:
增加了灵活性,可以满足不同大小的进程需求。根据常在系统中运行的作业大小情况进行划分(比如:划分多个小分区、适量中等分区、少量大分区)。
实现:
1.操作系统需要建立一个数据结构一分区说明表,来实现各个分区的分配与回收。每个表项对应一个分区,通常按分区大小排列。每个表项包括对应分区的大小、起始地址、状态(是否已分配)。
2.当某用户程序要装入内存时,由操作系统内核程序根据用户程序大小检索该表,从中找到一个能满足大小的、末分配的分区,将之分配给该程序,然后修改状
态为“己分配”。
优点:
实现简单,无外部碎片。
缺点:
1.当用户程序太大时,可能所有的分区都不能满足需求,此时不得不采用覆盖技术来解决,但这又会降低性能。
2.会产生内部碎片,内存利用率低。
4.3 动态分区分配
基本概念:
1.动态分区分配又称为可变分区分配。这种分配方式不会预先划分内存分区,而是在进程装入内存时,根据进程的大小动态地建立分区,并使分区的大小正好适合进程的需要。因此系统分区的大小和数目是可变的。
2.动态分区分配没有内部碎片,但是有外部碎片。
两种常用的数据结构:
空闲分区表
空闲分区链
回收内存的时,可能遇到的四种情况:
1.回收分区之后有相邻的空闲分区,会合并该分区。
2.回收分区之前有相邻的空闲分区,会合并该分区。
3.回收分区前、后有相邻的空闲分区,会将前后和自己一起合并。
4.回收分区前、后有没有相邻的空闲分区,可以考虑采用紧凑技术的合并。
内部碎片:
就是在分配给某个进程的内存区域中,如果有些部分没有用上,就称为内存碎片。
外部碎片:
就是指内存中某些空闲的分区由于大小而难以利用。
紧凑技术:
如果内存中空闲空间的总和本来可以满足某进程的要求,但由于进程需要的是一整块连续的内存空间,因此这些“碎片〞不能满足进程的需求。可以通过紧凑(拼湊, Compaction)技术来解决外部碎片。
5.动态分区分配算法
首次适应算法
算法思想:
每次都从低地址开始查找,找到第一个能满足大小的空闲分区。
如何实现:
空闲分区以地址递增的次序排列。每次分配内存时顺序查找空闲分区链(或空闲分区表),找到大小能满足要求的第一个空闲分区。
最佳适应算法
算法思想:
由于动态分区分配是一种连续分配方式,为各进程分配的空间必须是连续的一整片区域。因此为了保证当“大进程〞到来时能有连续的大片空间,可以尽可能名地留下大片的空闲区,即,优先使用更小的空闲区。
如何实现:
空闲分区按容量递增次序链接。每次分配内存时顺序查找空闲分区链 (或空闲分区表),找到大小能满足要求的第一个空闲分区。中间容量发生变化后需要重新对分区链(或分区表)
进行排序。
缺点:
每次都选最小的分区进行分配,会留下越来越多的、很小的、难以利用的内存块。因此这种方法会产生很多的外部碎片。
最坏适应算法
算法思想:
又称 最大适应算法,为了解决最佳适应算法的问题一即留下太多难以利用的小碎片,可以在每次分配时优先使用最大的连续空闲区,这样分配后剩余的空闲区就不会太小,,更方便使用。
如何实现:
空闲分区按容量递减次序链接。每次分配内存时顺序查找空闲分区链(或空闲分区表),找到大小能满足要求的第一个空闲分区。中间容量发生变化后需要重新对分区链(或分区表)进行排序。
缺点:
每次都选最大的分区进行分配,虽然可以让分配后留下的空闲区更大,更可用,但是这种方式会导致较大的连续空闲区被迅速用完。如果之后有 “大进程” 到达,就没有内存分区可用了。
邻近适应算法
算法思想:
首次适应算法每次都从链头开始查找的。这可能会导致低地址部分出现很多小的空闲分区,而每次分配查找时,都要经过这些分区,因此也增加了查找的开销。如果每次都从上次查找结束的位置开始检索,就能解决上述问题。
如何实现:
空闲分区以地址递增的顺序排列 (可排成一个循环链表)。每次分配内存时从上次查找结束的位置开始查找空闲分区链(或空闲分区表),找到大小能满足要求的第一个空闲分区。
缺点:
首次适应算法每次都要从头查找,每次都需要检索低地址的小分区。但是这种规则也决定了当低地址部分有更小的分区可以满足需求时会更有可能用到低地址部分的小分区,也会更有可能把高地址部分的大分区保留下来(最佳适应算法的优点)邻近适应算法的规则可能会导致无论低地址、高地址部分的空闲分区都有相同的概率被使用,也就导致了高地址部分的大分区更可能被使用,划分为小分区,最后导致无大分区可用。
5.5 四者对比
内存基本概念小结,欢迎大家交流学习!