操作系统学习笔记 3内存管理
200 Words|Read in about 1 Min|本文总阅读量次
熟悉完操作系统的第二篇章,开始学习第三篇章,关于操作系统的内存管理。
0猜你喜欢
操作系统系列文章
3内存管理
计算机启动后,通过BootLoader加载操作系统,让操作系统能够启动。操作系统加载到内存之后,会对计算机系统进行管理和控制。首先管理和控制的就是内存,这个篇章主要是操作系统如何管理物理内存。
主要内容
- 计算机体系结构/内存分层体系
- 地址空间 & 地址生成
- 连续内存分配
3.1计算机体系结构及内存分层体系
3.1.1计算机体系结构/内存分层体系
- 计算机体系结构
- 内存分层体系
- 在操作系统的内存管理范例
CPU主要完成了整个程序或者软件执行的控制,内存放置了程序的代码和处理数据,外设包括键盘鼠标等,不同外设有不同的作用,配合程序发挥更大的作用。比如把数据永远的保存到硬盘中。
3.1.2层次结构
操作系统需要在这个阶段把CPU访问物理内存有效地管理起来。内存包含的层次结构如下
从上到下CPU可访问的数据很多种类,比如寄存器,cache(高速缓存,一般现在的计算机都是三级缓存),主存和磁盘。
-
寄存器和cache
位于CPU内部,操作系统无法对这两种数据直接管理,它们属于有访问快但是容量小特性。放置的数据和指令是有限的。
-
主存
可以存储很多可以运行的程序,如果数据过大放不下需要将数据放到硬盘中,这就需要操作系统管理和控制。主存的数据属于一掉电数据就没了。需要在掉电前把数据放入硬盘中。
-
磁盘
掉电后,能够保存数据的类型。数据访问速度较慢,但是容量比较大。
可以发现越靠近CPU数据访问速度越快,容量越小,越到磁盘速度越慢,容量越大。数据访问速度越快,并且容量,需要操作系统去管理物理内存和虚拟内存,可以完成看起来不可能完成的任务。
3.1.3四个目标
操作系统需要完成的事情,有四个目标
抽象:不用考虑底层的细节,只需要访问连续的具体地址(逻辑地址空间)
保护:可以运行多不同应用程序,不同的应用程序可能会访问别的程序的地址空间,造成应用地址的破坏。有效的机制能够保护进程间的地址,使得地址在不同的应用程序间相互隔离。
共享:需要一个共享的空间,用于数据传递
虚拟化:在内存中放了很多应用程序,会出现内存不够的情况。正在运行的程序获取所需要的空间,可以采用最需要放到内存的数据放到内存中,暂时不需要的数据可放入硬盘中。
逻辑地址空间和物理地址空间
主存和硬盘属于物理地址空间,运行的程序属于逻辑地址空间
四个目标需要机制完成,机制包含了相关的手段
-
在操作系统中管理内存的不同方法
程序重定位
分段
分页
虚拟内存
按需分页虚拟内存
-
实现高度依赖与硬件
必须知道内存架构
MMU(内存管理单元):硬件组件负责处理CPU的内存访问请求
3.2地址空间与地址生成
3.2.1地址空间 & 地址生成
地址空间定义
地址空间生成
地址安全检查
地址空间
-
物理地址空间
是和硬件直接对应,比如内存条所代表的的主存和硬盘所代表的的另一种存储空间。物理地址空间的控制和管理,是由硬件来完成的。
-
逻辑地址空间
一个运行的程序他所拥有的空间,一维线性的空间,应用程序会比较访问,相关的控制等。
所有运行的程序,它所访问的逻辑地址空间,最终都落在一个物理内存中。比如每条指令,根据逻辑地址空间,它位于箭头指向的程序所指的位置(上图所示),但最终会放置咋主存中或者硬件中。至于放在主存还是硬盘中是由操作系统协调的,可以明确的说明这种映射关系需要操作系统有效的管理。
3.2.2逻辑地址生成
通过编译期,通过linker,通过loader就可以完成这个过程的建立。
- c程序通过编译可以把c程序,编译成汇编程序。c程序中,函数的名字,变量名字就是一种地址,是一种人容易理解的方式存在的
- 汇编程序,更加接近机器语言,但还是符号代表变量和函数的名字,相对机器语言也更好地让人理解阅读。
- 通过汇编器,可以转化成机器语言.o文件,起始地址都是从0开始,会把函数符号名、变量符号名转化为相应的地址。
- 大的程序是由多个小的程序组成的,可能使得不同的程序之间的地址相互访问。通过linker将这些.o文件最终变成单一的可执行文件exe file。exe file是一个单一的文件,可以在文件中执行暂时还存在硬盘中的程序。这个程序中地址已经做了一个全局的分布,不同的.o程序能够在单一的执行中有相应的定义,这个定义还不在内存中的一个位置。
- loader应用程序,让这个放在硬盘中的可执行程序放到内存中去运行。这一步会需要去完成把这个逻辑地址完成相应的分配,使得应用程序在内存中可以正常的跑。相对与执行程序,它会有相应的偏移量,偏移量可为0或者特定的偏移量。有了这个值,所有的程序都依照这个偏移量来正确的进行数据访问和指令的操作。从符号的逻辑地址到最终在内存中可以运行的具体的逻辑地址,这个过程有很多转换过程,这个过程不需要操作系统做任何帮助。
3.2.3这个指令所处的逻辑地址是怎么映射到物理地址上面去的
指令有自己的逻辑地址。需要把指令从内存中取出来,放在物理内存中的什么地方,这就有一个映射关系。
硬件中有MMU(内存管理单元)。MMU在有块区域表示这个映射关系(蓝色位置所示)。映射我们查表就可以知道,逻辑地址到物理地址的一个映射。逻辑地址和物理地址的关系,是需要通过操作系统完成的。
可以简化下面几个步骤
- CPU要执行某条指令的时候,它的ALU(计算逻辑单元)部件需要这条指令的内容,它会发出请求,发的请求带着参数就是逻辑地址。
- CPU的MMU会去查找逻辑地址的映射表,是否存在对应的物理地址,如果有的话就匹配。
- 如果没有的话就会从内存(主存)中找。如果找到了,CPU的控制器会给主存发起请求,需要一个物理地址的内容(指令的内容)。
- 主存会把内存的内容通过总线传给CPU,CPU拿到这条指令的内容就可以对它执行操作。
3.2.4地址安全检查
操作系统首先要确保每一个程序有效访问的地址空间。
第一部分是起始地址,第二个是长度。通过这两部分可以知道这个区域是这段程序的合理范围,超出区域的访问是这个程序不合法的访问。
一旦CPU去执行某条指令的时候,它会查询这个map。这个map会指出来,他访问的地址,逻辑地址是否满足区域的限制。然后找到对应的物理地址的位置,数据和指令取回来。一旦不满足,CPU就会产生memory异常(内存访问异常),
3.3连续内存分配
- 内存碎片问题
- 分区的动态分配(第一适配、最佳适配、最差适配)
- 压缩式碎片整理和交换式碎片整理
3.3.1内存碎片问题
内存碎片问题就是空闲内存不能被利用
外部碎片:在分配单元间的未使用内存
内部碎片:在分配单元中的未使用内存
3.3.2连续分配内存:内存碎片与分区的动态分配
操作系统会对应的三种算法,分别是第一匹配分配、最佳匹配分配、最差匹配分配。
为了使得程序能够得到连续的区间,程序中的数据可以有连续的空间。
3.3.2.1第一匹配分配
为了分配n字节,使用第一个可用空闲块以致块的尺寸比n大。
3.3.2.2最佳匹配分配
为了分配n字节,使用最小的可用空闲块,以致块的尺寸比n大
3.3.2.3最差匹配分配
为了分配n字节,使用最大可用空闲块,以致块的尺寸比n大。
3.3.2.4总结
到底哪一种是做好的算法?其实没有最好的算法这一说。应用程序的请求是随机产生的,根据特定的场景产生有各自的特点,应用程序一会需要大的空间块,一会需要小的空间块,需求是随机的可变的,不存在一种可以满足所有的需求。
第一匹配分配 | 最佳匹配分配 | 最差匹配分配 | |
---|---|---|---|
基本原理 | 简单实现 | 1)为了避免分割大空间块2)为了最小化外部碎片产生的尺寸 | 为了避免有太多微小的碎片 |
需求 | 1)按地址排序的空闲块列表2)分配需要寻找一个合适的分区3)重分配需要检查,看是否自由分区能合并于相邻的空闲分区(若有) | 1)按尺寸排列的空间块列表2)分配需要寻找一个合适的分区3)重分配需要搜索及合并于相邻的空间分区(若有) | 1)按尺寸排列的空闲块列表2)分配很快(获得最大的分区)3)重分配需要合并于相邻的空闲分区,若有就调整空闲块列表 |
优势 | 简单,易于产生更大空闲块,向着地址空间的结尾 | 当大部分分配的尺寸是小尺寸时非常有效,比较简单 | 假如分配是中等尺寸效果最好 |
劣势 | 产生外部碎片和不确定性 | 产生外部碎片,重分配慢和易产生很多没用的微小碎片(不怎么样) | 重分配慢,产生外部碎片和易于破碎大的空闲块以致大分区无法被分配 |
3.3.3连续分配内存:压缩式与交换式碎片整理
3.3.3.1压缩式碎片整理
- 重置程序以合并孔洞
- 要求所有程序是动态可重置的
这里面有四个程序,还剩余5个内存块。如果有第五个程序想占用这5个内存块,其实不能够满足需求,因为这5个内存块是不连续的。
目前可以采用挪动内存块的方式,如上图3-1右边所示,p2,p3,p4都往上去挪动,使得空间块能够空出来。这个过程也是内存拷贝的过程。
但其实这个过程不是单纯拷贝这个简单,还需要考虑何时重置和开销。程序在运行的时候显然不满足要求,可以在程序的停止过程,这个时候程序没有占用CPU执行,处于等待状态。另外开销问题,程序从一个地方拷贝到另一个地方,也许速度会很快,但是内存中频繁做这类操作,内存拷贝的开销也会增大,甚至会影响整个系统正常的执行。纯靠软件的话,存在很大的开销的问题。
3.3.3.2交换式碎片整理
另外,可以利用硬盘。可以把硬盘当做内存的后备。
这里P1,P2,P3应用程序正在等待运行,P3这个时候运行,且在P3应用执行过程中需要更多的内存,从3个内存块到6个内存块。而此时已经没有更多的内存,通过压缩式碎片整理的方法,已经不起作用。由于P1,P2,P4,已经把空间占满了,只能把硬盘当做备份(类似华容道原理)。P4占了3个内存块,由于P4正在等待某个事件,这个时候把P4占用挪到硬盘上去,3个空闲内存块正好可以让P3使用。P4数据并没有消失,只是从主存放到了硬盘上去。P4需要执行的时候,再从硬盘拷贝到主存中去。
但其实这个过程拷贝到硬盘中去,还需要考虑哪些程序交换和交换的时机。如果程序本身比较大,主存和硬盘的交换开销也是很大的。