【清华大学】操作系统 陈渝 Part3 ——物理内存管理 之 连续内存分配

3.1计算机体系结构及内存分层

了解了操作系统启动和加载,那么操作系统启动以后要做什么工作呢?
当操作系统加载到内存后,它要对整个计算机系统进行管理和控制。首先要控制的就是内存

计算机体系机构

计算机基本硬件结构:

  • CPU:完成整个程序或软件的控制
  • 内存:放置程序的代码和处理的数据
  • 外设(I/O设备):键盘,鼠标,硬盘

在这里插入图片描述

内存体系层次

内存不仅仅包含主存或者物理内存
CPU要访问的指令和数据处在不同的个地方。
CPU可以直接访问的是寄存器和Cache,它们位于计算机CPU内部芯片上,操作系统对它没有办法直接进行管理,他们的速度很快,容量很小,因此能够访访问的数据和指令是有限的。
计算机系统里还有一块很大的存储区域,叫做主存(物理内存),主要放置操作系统本身以及要运行的程序代码。主存中可以同时存放很多个可以运行的程序,某些时候对内存需求比较大,在内存中放不进去的数据要放到硬盘上去。另外,主存掉电以后数据就会消失,需要永久保存的数据和代码要放在硬盘中,使得掉电以后,数据可以永久保存下来,上电以后,再把数据读入到主存中来。硬盘速度慢,但是容量大。
在这里插入图片描述
对于编程人员来说,我们希望运行的程序可以同时满足:1.数据访问快;2.数据存储空间大。操作系统可以通过管理来完成我们想要的性能。

操作系统在管理内存时需要实现哪些目标?

  1. 抽象:因为有了操作系统管理,使应用程序在运行时候不用考虑底层的细节,不需要考虑物理内存在什么什么地方,不需要考虑外设在什么地方,只需要访问一段连续的地址空间——逻辑地址空间
  2. 保护:内存中可以运行多个不同的应用程序,多个不同应用程序之间可能会去访问/破坏他人的进程地址空间,因此需要一种保护机制,需要操作系统来实现程序的隔离的地址空间——独立地址空间
  3. 共享:进程之间可能会交互,使进程彼此之间安全可靠传递数据——访问相同内存
  4. 虚拟化:当内存中放了很多应用程序的时候,会出现内粗不够的情况,怎么样让正在运行的程序获得它需要的运行内存空间呢?把最需要内存的数据暂时放在内存中,把暂时不需要访问的数据放进硬盘中——更多的地址空间
    在这里插入图片描述
    上图中:有4个放在内存中的程序。P1正在占用CPU,P2,P3,P4在等待,P4需要等待时间最久,P4需要访问的数据没有必要放在内存中,P1需要更多空间,因此把P4访问的数据在操作系统帮助下导入到硬盘上,P1因此得到更多空间。所以在内存中,就剩下P1,P2,P3,P4的代码和数据在磁盘上。当P1不执行时,可以把CPU控制权交给P2,P2不执行把CPU控制权交给P3。

管理内存方法

在操作系统中管理内存的不同方法:

  • 程序重定位
  • 分段
  • 分页
  • 虚拟内存
  • 按需分页虚拟内存

因为操作系统是软件,要实现上述管理内存功能,高度依赖硬件
因此必须知道内存架构
MMU(内存管理单元):硬件组件负责处理CPU的内存访问请求

3.2地址空间 & 地址生成

地址空间定义

  • 物理地址空间:是和硬件直接对应的,比如:内存条代表的主存;硬盘代表的另一种存储空间。物理空间的管理和控制是由硬件完成的。
  • 逻辑地址空间:运行的程序所看到的地址空间,程序看见的地址空间更简单,是一维线性地址空间,应用程序很容易去访问相关数据。

两者之间是如何建立联系的?运行的程序所访问的逻辑地址空间最终都是落实在物理空间中存在的。
在这里插入图片描述

地址生成

以C程序为例:变量的名字就是一个逻辑地址
汇编程序:符号代表变量和函数名字
在这里插入图片描述
应用程序在访问一段指令时,指令所处的逻辑地址是如何对应到物理内存中?
CPU要运行一段指令,需要把指令存内存中取出来,放在物理内存中什么地方?CPU是不知道,它只知道一个逻辑地址,它会查找这个逻辑地址和物理地址的对应关系。MMU完成逻辑地址和物理地址的映射。
在这里插入图片描述

地址安全检查

操作系统一个很重要的目标是需要确保放在内存中的程序相互之间不干扰,需要确认每一个程序访问的地址空间是否为合法的,没有超过访问范围。
在这里插入图片描述

3.3连续内存分配:内存碎片 & 分区的动态分配

内存碎片问题

碎片的定义
当给运行的程序分配一块空间后,会出现一些无法进一步利用的空间,称之为碎片。
碎片分类:外部碎片 & 内部碎片
外部碎片:在分配单元之间的无法使用的内存
内部碎片:在分配单元之内的无法使用的内存
两种碎片是操作系统想要尽量避免的,希望有内存分配的方法有效的减少碎片。

那么,站在操作系统的角度来看,什么时间提供连续内存分配呢?

分区的动态分配

简单的内存管理方法

  • 当一个程序准许运行在内存中时,操作系统需要把应用程序加载到内存中去,这时需要给内存分配一个连续的区间让程序运行起来;
  • 应用程序在运行时,分配一个连续的内存空间给它来访问数据,也就是说操作系统要提供给应用程序需要的内存空间。

为此,操作系统需要管理整个空闲/非空闲的内存空间,有数据结构和算法来进行管理

分配策略

1. 首次适配:第一匹配分配

基本原理
从低地址开始,找到第一个满足适配的空闲块来分配给应用程序。

简单实现

需求
空闲块按照地址排序;
分配需要寻找一个合适的大小分区;
回收问题,重分配需要检查,看是否自由分区能合并于相邻的空闲分区(若有),合并可以形成更大的空间块满足大程序的需求。

优势 劣势
简单 容易产生外部碎片
易于产生更多更大的空间块 ,向着地址空间的结尾 不确定性

在这里插入图片描述
2. 最优适配:最佳匹配

基本原理
找到最适合分配请求的空闲块。
什么是最适合?空闲块的粒度和请求大小差值最小

实现
为了避免分割大的空闲块;
为了最小化外部碎片产生的尺寸;

需求
空闲块按照尺寸排列;
分配需要寻找一个合适的分区;
回收问题,重分配需要搜索及合并于相邻的空闲分区(若有)

优势 劣势
比较简单 产生很多小的碎片,不利于后续空间管理
对大部分分配是小尺寸时非常有效 重分配慢

在这里插入图片描述

3. 最差适配 :最差匹配原则
基本原理
找到和分配请求大小差距最大的空闲块。

实现
为了避免有太多微小的碎片

需求
空闲块按尺寸大小排列;
分配很快(获得最大的分区)
回收问题,重分配需要合并于相邻的空闲分区,若有,然后重新调整空闲块列表

优势 劣势
假如分配是中等尺寸效果最好 重分配慢
—— 外部碎片
—— 易于破碎大的空闲块以至于大的分区无法被分配

在这里插入图片描述

发布了45 篇原创文章 · 获赞 4 · 访问量 2518

猜你喜欢

转载自blog.csdn.net/keke_Memory/article/details/105047205