3.1.1 内存的基础知识
内存可存放数据。程序执行前需要先放到内存中才能被CPU处理--缓和CPU与磁盘之间的速度矛盾。
内存中也有一个一个的“小房间”,每个小房间就是一个“存储单元”;内存地址从0开始,每个地址对应一个存储单元;如果计算机“按字节编址”,则每个存储单元大小为1字节;如果字长为16位的计算机“按字编址”,则每个存储单元大小为1个字,每个字的大小为16个二进制位。
1K=2^10 1M=2^20 1G=2^30
装入的三种方式:
- 绝对装入:在编译时,如果知道程序将放到内存中的哪个位置,编译程序将产生绝对地址的目标代码。装入程序按照装入模块中的地址,将程序和数据装入内存。绝对装入只适用于单道程序环境(当时还没产生操作系统)。灵活性较差,同样的程序换了一台电脑可能要重写。
- 静态重定位:又称可重定位装入。编译、链接后的装入模块的地址都是从0开始的,指令中使用的地址、数据存放的地址都是相对于起始地址而言的逻辑地址。可根据内存的当前情况,将装入模块装入到内存的适当地方。装入时对地址进行“重定位”,将逻辑地址变换为物理地址(地址变换是在装入时一次完成的)。静态重定位的特点是在一个作业装入内存时,必须分配其要求的全部内存空间(连续的),如果没有足够的内存,就不能装入该作业。作业一旦进入内存后,在运行期间就不能再移动,也不能再申请内存空间。(用于早期的多道批处理操作系统)
- 动态重定位:又称动态运行时装入。编译、链接后的装入模块的地址都是从0开始的。装入程序把装入模块装入内存后,并不会立即把逻辑地址转换为物理地址,而是把地址转换推迟到程序真正要执行时才进行。因此装入内存后所有的地址依然是逻辑地址,这种方式需要一个重定位寄存器的支持。重定位寄存器存放装入模块存放的起始地址。采用动态重定位时允许程序在内存中发生移动。并且可将程序分配到不连续的存储区中;在程序运行前只需装入它的部分代码即可投入运行,然后在程序运行期间,根据需要动态申请分配内存;便于程序段的共享,可以向用户提供一个比存储空间大得多的地址空间。(现代操作系统)
链接的三种方式:
- 静态链接:在程序运行之前,先将各目标模块以及它们所需的库函数链接成一个完整的可执行文件(装入模块),之后不再拆开;
- 装入时动态链接:将个目标模块装入内存时,边装入边链接的链接方式;
- 运行时动态链接:在程序执行中需要该目标模块时,才对它进行链接。优点是便于修改和更新,便于实现对目标模块的共享。
(链接是确认完整的逻辑地址,而装入时确认最终的物理地址)
3.1.2 内存管理的概念
操作系统负责内存空间的分配与回收;
操作系统需要提供某种技术从逻辑上对内存空间进行扩充;
操作系统需要提供地址转换功能,负责程序的逻辑地址与物理地址的转换----三种装入方式;
操作系统需要提供内存保护功能,保证各进程在各自存储空间内运行,互不干扰。
3.1.3 覆盖与交换
覆盖技术
按照自身逻辑结构,让那些不可能被同时被访问的程序段共享同一个覆盖区。
必须由程序员声明覆盖结构,操作系统完成自动覆盖。缺点:对用户不透明,增加了用户编程负担。
交换技术
(换出的进程放在哪里是存储在pcb中的,所以pcb要在内存中)
覆盖是在同一个程序或进程中的,交换是在不同进程(或作业)之间的
3.1.4 连续分配管理方式
外部碎片指的是还没有被分配出去(不属于任何进程),但由于太小了无法分配给申请内存空间的新进程的内存空闲区域。外部碎片是除了任何已分配区域或页面外部的空闲存储块。
如果系统采用的数据结构是“空闲分区表”,各表项的顺序不一定按照地址递增顺序排列,具体的排列方式需要根据动态分区分配算法来确定。
(动态重定位装入,还要修改重定位寄存器中的基地址)
3.1.5 动态分区分配算法
首次适应算法
算法思想:每次都从低地址开始查找,找到第一个能满足大小的空闲分区。
如何实现:空闲分区以地址递增的次序排列。每次分配内存时顺序查找空闲分区链(或空闲分区表),找到大小能满足要求的第一个空闲分区。
最佳适应算法
算法思想:由于动态分区分配是一种连续分配方式,为各进程分配的空间必须是连续的一整片区域。因此为了保证当“大进程”到来时能有连续的大片空间,可以尽可能多地留下大片的空闲区,即,优先使用更小的空闲区。
如何实现:空闲分区按容量递增次序链接。每次分配内存时顺序查找空闲分区链(或空闲分区表),找到大小能满足要求的第一个空闲分区。
缺点:每次都选最小的分区进行分配,会留下越来越多的、很小的、难以利用的内存块。因此这种方法会产生很多的外部碎片。
最坏适应算法,又称最大适应算法
算法思想:为了解决最佳适应算法的问题--即留下太多难以利用的小碎片,可以在每次分配时优先使用最大的连续空闲区,这样分配后剩余的空闲区就不会太小,更方便使用。
如何实现:空闲分区按容量递减次序连接,每次分配内存时顺序查找空闲分区链(或空闲分区表),找到大小能满足要求的第一个空闲分区。
缺点:每次都选最大的分区进行分配,虽然可以让分配后留下的空闲区更大,更可用,但是这种方式会导致较大的连续空闲区被迅速用完。如果之后有“大进程”到达,就没有内存分区可用了。
邻近适应算法
算法思想:首次适应算法每次都从链头开始查找的。这可能会导致低地址部分出现很多小的空闲分区,而每次分配查找时,都要经过这些分区,因此也增加了查找的开销。如果每次都从上次查找结束的位置开始检索,就能解决上述问题。
如何实现:空闲分区以地址递增的顺序排序(可排成一个循环链表)。每次分配内存时从上次查找结束的位置开始查找空闲分区链(或空闲分区表),找到大小能满足要求的第一个空闲分区。
首次适应算法每次都要从头查找,每次都需要检索低地址的小分区。但是这种规则也决定了当低地址部分有更小的分区可以满足需求时,会更有可能用到低地址部分的小分区,也会更有可能把高地址部分的大分区保留下来(最佳适应算法的优点)。
邻近适应算法的规则可能会导致无论低地址、高地址部分的空闲分区都有相同的概率被使用,也就导致了高地址部分的大分区更可能被使用,划分为小分区,最后导致无大分区可用(最大适应算法的缺点)。
综合来看,四种算法中,首次适应算法的效果反而更好。
3.1.6 基本分页存储管理的基本概念
(按字节编址)
3.1.7 基本地址变化机构
基本地址变换结构可以借助进程的页表将逻辑地址转换为物理地址。
通常会在系统中设置一个页表寄存器(PTR),存放页表在内存中的起始地址F和页表长度M。进程未执行时,页表的始址和页表长度放在进程控制块(pcb)中,当进程被调度时,操作系统内核会把它们放到页表寄存器中。
进程页表通常是装在连续的内存块中的。
页式管理中地址是一维的。
3.1.8 具有快表的地址变换机构
快表,又称联想寄存器(TLB,translation lookaside buffer),是一种访问速度比内存快很多的高速缓存(TLB不是内存),用来存放最近访问的页表项的副本,可以加速地址变换的速度。与此对应,内存中的页表常称为慢表。
进程切换时,快表的内容会被清空。(快表也是个硬件)
3.1.9 两级页表
根据局部性原理可知,很多时候,进程在一段时间内只需要访问某几个页面就可以正常运行了。因此没必要让整个页表都常驻内存。
3.1.10 基本分段存储管理
3.1.11 段页式管理方式
一个进程对应一个段表,但一个进程可能对应多个页表。
3.2.1 虚拟内存的基本概念
3.2.2 请求分页管理方式
在具有快表机构的请求分页系统中,访问一个逻辑地址时,若发生缺页,则地址变换步骤是:查快表(未命中)---查慢表(发现未调入内存)---调页(调入的页面对应的表项会直接加入快表)---查快表(命中)---访问目标内存单元
3.2.3 页面置换算法
最佳置换算法可以保证最低的缺页率,但实际上,只有在进程执行的过程中才能知道接下来会访问到的是哪个页面。操作系统无法预判页面访问序列。因此,最佳置换算法是无法实现的。
若分配四个内存块,缺页次数为10次;分配三个内存块,缺页次数为9次。
Belady异常:当为进程分配的物理块数增大时,缺页次数不减反增的异常现象。
只有FIFO算法会产生Belady异常。另外,FIFO算法虽然实现简单,但是该算法与进程实际运行时的规律不适应,因为先进入的页面也有可能最经常被访问。因此,算法性能差。
该算法的实现需要专门的硬件支持,虽然算法性能好,但是实现困难,开销大。
该算法实现简单,算法开销小;但未考虑页面是否被修改过。
该算法开销较小,性能也不错。
3.2.4 页面分配策略、抖动、工作集
系统会锁定一些页面,这些页面中的内容不能置换处外存(如:重要的内核数据可以设为“锁定”)
刚刚换出的页面马上又要换入内存,刚刚换入的页面马上又要换出外存,这种频繁的页面调度行为称为抖动,或颠簸。产生抖动的主要原因是进程频繁访问的页面数目高于可用的物理块数(分配给进程的物理块不够)。
为进程分配的物理块太少,会使进程发生抖动现象。为进程分配的物理块太多,又会降低系统整体的并发度,降低某些资源的利用率。为了研究应该为每个进程分配多少个物理块,Denning提出了进程“工作集”的概念。
标签:--,分区,算法,王道,装入,地址,内存,空闲 From: https://www.cnblogs.com/summerw/p/17405849.html