《现代操作系统》03章 存储管理(一)

又是周末到来时,学习成果分享之!

0 前导

帕金森定律:不管存储器有多大,程序都可以把它填满(我的理解:即使你的手机存储空间有128G甚至256G,你也会把它装满或是出现运行卡顿,有些信息的使用频率过低但任然会占用存储资源)

程序员的梦想:廉价、私有、无限、高速、永久(掉电不丢失)的存储器

但愿程序员的梦想能由你我来实现!

现实的存储体系:一个分层存储的抽象模型,这个模型在第一章第三节中略微提及,传送门

这个抽象模型需要管理,操作系统中的存储管理器(memory manager)可以胜任,它记录、分配、回收内存资源。

注意:最底层的高速缓存由硬件完成,本章将由简入繁的介绍针对编程人员的内存模型、及内存*的优化管理、磁盘的管理为下一章内容*


1 无存储器抽象

最简单的存储器抽象就是根本没有抽象,这样程序直接访问物理内存,例如汇编语言MOV R1,1000的意思是将地址1000处的内容移动到Register1中(也有可能相反,取决于机器的型号)。(如果学过简单的单片机汇编语言应该很容易理解)

无存储器抽象操作系统的三种主要结构

在这里插入图片描述

这种无存储抽象的设定导致同一时刻内存中仅能存在一个进程

第一种方案现在很少使用,用户程序可能损毁系统
第二种在掌机和嵌入式系统中应用
第三种方案用于早起PC(例如MS-DOS),ROM中的驱动程序称为BIOS,用户程序可能摧毁系统


无存储抽象运行多道程序

以IBM360早期模型举例

内存划分为2KB的块,每个块拥有四位保护键(存储在CPU特殊寄存器中)
PSW中有一个四位码(表示当前允许访问的块,只有操作系统可以修改),当进程将要访问的块与PSW不符时,操作系统会进行相应处理,避免进程、操作系统间的干扰

由于程序员编写进程使用的绝对地址,导致多个进程被装载后会出现不可避免的访问越界,这需要一个装载器,它的任务是在装载进程时要将进程中有关地址访问的绝对地址+偏移地址,例如存储在磁盘中的进程有一个跳转语句JMP 28,而该进程被装填在地址16384处,则需要将该语句修改为JMP 16412

在大型机、小型机、台式机、笔记本中已经看不到这种构造的内存抽象,但是在简单地嵌入式系统(微波炉、冰箱、智能卡等)中还存在着他们的身影。操作系统可以以库的形式实现,例如ecos系统


2 地址空间

无存储抽象的系统将物理地址直接暴露给进程,(单CPU时)很难实现要求多进程快速响应的应用环境,并且还可能出现应用程序破坏系统的情况。

2.1 何为地址空间

地址空间为程序提供一种抽象内存,地址空间是一个进程可用于寻址内存的一套地址集合。在每个程序的地址空间内,程序员不用再担心两个进程访问相同的地址时会发生冲突

【例如两个进程中都有JMP 28,在运行时会被映射到真实物理内存(如16384)而未必是28】

地址空间的概念在其他领域同样存在,例如IP地址也有地址空间(IPV4:0~2*32-1)、网站的域名也是一个地址空间(数字字母下划线+.com/cn/org/edu等等)


基址寄存器与界址寄存器

这种方法曾经常见,随着CPU的发展和抽象技术的迭代,这种方法不再使用了,但我们还是要学习一下其中的思想。

一种简单地动态重定位

给CPU配置两个特殊的硬件寄存器(一般只有操作系统有权限对寄存器值进行修改):基址寄存器界址寄存器

程序的运行将按照以下机制执行:

在这里插入图片描述

缺点:每次的内存访问都要进行一次比较和加法运算,比较速度较快,但加法(由于进位)若没有特殊的运算电路仍然会耗费时间而拖慢运行速度


2.2 交换技术

内存交换系统的大致流程:

在这里插入图片描述

空闲区(hole):也叫空洞,内存中空闲的空间
内存紧缩(memory compaction):向下移动进程将分散的Hole合并成更大的Hole,消耗CPU时间多,一般不使用

内存该分配多少?

有些进程的大小是固定的,直接装入即可,有些进程会存在动态变量(从堆向下增长动态的分配内存,在栈向上增长存放返回地址和局部变量),这时需要给装入内存的进程分配一些额外的预留空间。

注意:当进程换出到磁盘时按照实际使用内存的大小交换,这要不会浪费磁盘空间。

在这里插入图片描述

如果预留空间使用完,此时内存中有足够的Hole,将其交换到更大的Hole;若没有足够的Hole则交出内存,回到磁盘等待足够的Hole,或者被终止。


2.3 空闲内存管理

老王今有农田128亩(内存128K),有租户(进程)来租地,怎们把地分给他们呢。老王找计算机系毕业的儿子出主意。

2.3.1 位图与存储管理

小王立刻想到了学过的位图,跑出去买了一袋石灰粉,用石灰粉按照2亩一格(分配单位)地把128亩地分成了64份;他给每格地编了号并在他的电脑里新建了一张Excel表格(位图)存放每格地的使用情况

在这里插入图片描述

Excel中1表示占用0表示空闲

分配单元的大小影响内存管理的效率:

大单元小单元
位图小,占用空间小位图大,占用空间大
产生较大空间浪费(一格未占满)产生较小的浪费

位图的搜索效率很低:加载新的进程需要在位图中搜索连续的0串,而有些0串跨越了字节(例如 11111000 00000111),效率大大降低.

2.3.2 使用链表的存储管理

有新的租户来找老王租地,老王要凑在电脑上找半天有没有足够大的连续的地租给租户,看的是头晕眼花,赶紧又把小王叫过来让他改进改进。

小王琢磨了一会,想到了一种学过的数据结构——链表,顿时心生一计,抄起电脑就是干。

在这里插入图片描述

链表是一种利用指针连接的数据结构,就像一根链条,每个链节都可存放一些数据或指针,链表的查找、创建和删除都非常的迅速,因此效率较高。

P代表进程 H代表空闲区,第一位数字代表起始编号,第二位数字代表该区域的长度

使用双向链表可以在进程退出时更方便的进行相邻Hole的合并

这样一来,老王只要搜索有没有大小适合的空闲节点,按照节点信息寻找对应的起始地块即可,然后根据情况修改链表中的信息。

首次试配算法(first fit)

已知进程要使用的内存大小,从表头顺序搜索链表,找到足够长的空闲区;若空闲区长度等于需求,将节点修改为进程占用状态;若空闲区大于需求,将空闲区分为两块,一块存放进程,一块继续作为空闲区,同时增加一个进程占用节点,并修改空闲区节点的起始编号和长度

下次试配算法(next fit)

在这次搜索完成后记录位置,下次从该位置开始搜索,其他同首次试配算法。性能略低于首次试配算法

最佳试配算法(best fit)

从头到尾搜索一遍,找到适合将要换入进程的最小空闲区。
缺点:搜索速度慢,浪费内存比首次试配或下次适配还严重(因为最佳适配产生了许多小的无法使用的空闲区)

加一点改进:将进程链表和空闲区列表分离,在寻找空闲区时不用经过进程占用节点,搜索速度大大提高。并且对空闲区按大小进行排列,再次提高搜索速度。(此时使用首次试配与最佳适配速度相同,下次试配无意义)
缺点:两张表在其中之一改变时需要完成同步,延长了进程释放内存的时间

该算法著名并广泛使用

快速试配算法(quick fit)

为常用大小的空闲区维护专用链表

在这里插入图片描述

21K的空闲区可以就近放在20K下,也可以单独开一个链表存放,这就看如何决策了

由此来快速匹配合适的空闲区


X 往期文章

《现代操作系统》02章 进程与线程(三)

今天,我是数据库的BOS(读者-写者问题)

哲学家不会吃饭了,我们快来帮帮他们(C语言、进程通信)

《现代操作系统》02章 进程与线程(二)

《现代操作系统》02章 进程与线程(一)

《现代操作系统》01章 基本概念

Python+OpenCV+imutils的简单图片处理(放缩、翻转、旋转、灰度RGB提取)

python手写K-means实现二维聚类.


如果文中有误,还请在评论区指正。这里是海小皮,我们一同进步!!!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值