设为首页 加入收藏

TOP

【操作系统】内存分配(一)
2023-07-23 13:27:19 】 浏览:111
Tags:

写在前面

  本系列的文章是博主边学边记录的,可能不是特别的正确,因为会加上博主自己的理解,仅供参考。

 

正文:

  为了能够将用户程序装入内存,必须为它分配一定大小的内存空间。常见的分配方式有:

1.连续分配

  连续分配方式是最早出现的一种存储器分配方式,该分配方式为一个用户程序分配一个连续的内存空间。常见的连续分配方式有:

  1.单一连续分配

  单一连续分配适合早期的单道批操作系统,在用户区中,仅装入一道用户程序。整个内存的用户空间由该程序独占。这样的存储器分配方式称为单一连续分配。

  2.固定分区分配

  在多道程序系统中,为了在内存中装土多道程序,且这些程序之间又不会发生相互干扰,于是将整个用户空间划分成若干隔固定大小的区域。每个分区中只装入一道作业。这样形成了最早、也是最简单的一种可运行多道程序的分区式存储管理方式。

划分分区的方法:

  1.将用户空间划分成若干个固定大小的分区

    这种分配方式缺乏灵活性。但是对于利用一台计算机同时控制多个相同大小对象的场合,这种划分方式比较方便和使用。

  2.将用户空间划分成若干个大小不定的分区

    这种分配方式灵活性较高,通常式根据用户的需求来进行划分。为不同大小的进程分配不同的内存空间。

  分区表:

  为了便于内存的管理,通常将内存按照其大小进行排队,并为之建立一张分区使用表。

  分区表包括每个分区的起始地址,大小、状态等。

 

 

 

  3.动态分区分配

  为了实现动态分区分配,系统配置了相应的一些数据机构。用以描述空闲分区和已分配分区的情况。常见的数据结构有:

  1.空闲分区表

  在系统中设置一张空闲分区表,用户记录每个空闲分区的情况。包括分区号、大小、起始地址等。

  2.空闲分区链

  以链表形式组织空闲分区。

  3.动态分区分配算法

  为了实现动态分配呢,通常将系统中的空闲分区链接成一个链。下面介绍下基于顺序搜索的动态分区分配算法:

  所谓顺序搜索,是指依次搜索空闲分区链上的空闲分区,去寻找一个其大小能够满足要求的分区。常见的算法有:

  1.首次适应算法 FF

  特点:

  空闲分区链以地址递增的次序链接。

  流程:

  每次都从链首开始顺序查找,直至找到一个大小能满足要求的空闲分区为止。然后进行切割分配。

  优点:

  该算法优先利用内存中低地址的部分的空闲分区,从而保留了高地址部分的大空闲区。为大作业分分配大的内存空间创建了条件。

  缺点:

  1.每次查找都从头部开始,会增加查找可用空闲分区的开销

  2.低地址部分不断被划分,会留下很多难以利用的小空间,也就是外部碎片。浪费内存空间。

 

  2.循环首次适应算法 NF

  区别于首次适应算法,NF不再是每次都从链首开始查找,而是从上次找到的空闲分区的下一个空闲分区开始查找,直至找到一个能满足要求的空闲分区。

  3.最佳适应算法 BF

  最佳适应算法,每次分配空间的时候,总是把能满足要求、又是最小的空闲分区分配给作业。避免"大材小用"

  同样也是从递增的方式形成空闲链表。每次分配完内存后,要进行及时的调整,保证链表的递增性。

  该种分配方式,也同样有可能造成碎片化。

  4.最坏适应算法 WF

  以递减的方式形成空闲链表,分配作业的时候,总是挑选一个最大的空闲分区,从中分割一部分存储空间给作业使用。

  缺点:

  导致存储器中缺乏大的空闲分区,所以称为最坏适应算法。

 

  提一个问题,BF和WF真的就是最好或者最坏的吗?

  其实不然,BF看似每次分配的都是最佳的方式,但是每次分配后所切割下来的剩余部分总是最小的。这样会形成大量的碎片

  而WF,由于每次都是从大空间中切分出去要分配的空闲,可使剩下的空闲分区不至于太小,产生碎片的可能性小。对中、小型作业有利。WF查找效率也很高,查找的时候只需要看第一个分区能否满足作业要求即可。

  可见,没有最好和最坏一说,各有所长,也各有所短。

 

  4.动态可重定位分区分配

   首先在这里面涉及一个"紧凑"的概念,就是将内存中不相邻的作业移动,使得之间间距的空间碎片聚集到一起,形成一个空用的空间。看下图应该就懂了.......

 

  可以看到后,紧凑后,空间得以重新利用。但是程序的地址也发生了改变。所以在每次紧凑后,都必须对移动的程序和数据进行重定位。但是这样做,很是麻烦。于是引入了动态重定位:

  为了使得地址的转换为不会影响到指令的执行速度,必须有硬件地址变换机构的支持。于是引入一个重定位寄存器。用它来存放程序在内存中起始地址。

 

 

  2.离散分配

  上面我们了解了连续分配会形成许多碎片,虽然可以通过紧凑方法将许多碎片拼接成可用的大块空间,但是必须付出很大的开销。如果允许将一个进程直接分散的装入去多不相邻接分区中,便可以充分的利用内存空间。而无须再进行紧凑。

  基于这一思想,产生了离散分配方式,根据离散分配时所分配地址空间的基本单位的不同,又可以将离散分配分为以下三种:

  1.分页存储管理方式

  分页存储管理方式,个人理解的是将用户程序的离散的存入到不同的物理块中,但是为了找到这些程序的地址,需要用一个数据结构来记录。这个数据结构就是页。当然一般情况下将页组织起来,形成该程序的页表。从而让系统得知该程序分配在内存中的哪些物理块中。

  补充一下分页涉及的概念:

  1.页面。分页存储管理将进程的逻辑地址空间分成若干个页,并为各页加以编号。同时也将内存的物理地址空间分成若干个块。

  一页对应一个块。在进行分配内存的时候,以块为单位,将进程中的若干页分别装入到多个可以不相邻的物理块中。

  2.页面大小:顾名思义,但是页面大小要适中选择,不能过大也不能过小。

  3.地址结构

  分页地址中的地址结构:

  

 

 

  4.页表

 

    为了保证进程能够在内存中找到每个页面所对应的物理块,系统为每个进程建立了一张页面映像表。简称为页表。

 

  

 

 

   TLB(Translation Look aside Buffer) /快表:

  页表是存放在内存中的,cpu每次存取一个数据的时候,都要访问两次内存。第一是访问页表,从中找到指定页的物理块号,形成物理地址。第二次是访问该物理地址,并写入或者取出数据。可见效率是比较低的。

  为了提高地址的变换速度,可以设置一个缓冲寄存器,也就是TLB。用来存放之前访问的那些页表项。再进行查找的时候,可以先查找TLB。如果命中,可直接读出改页对应的物理块号,并写入物理地址寄存器中。

  没有命中的化,还是需要再次访问页表。后期把本次页表项存入快表中。从而提高访问的速度。

 

 

 

 

 

 

  2.分段存储管理方式

  分段存储管理方式主要是为了满足用户在编程和使用上多方面的要求。像主程序段、子程序段、数据段、堆栈段等等。因此分段存储大小并不固定,因为每个段的大小并不是固定的。

  分段地址的结构:

  

 

 

   段表:和页表的作用是一样的,方便程序寻址。看一下段表的组成:

    

 

 

  当采用分段的方式分配空间的时候,需要先比较分区的大小也就是段长是否合适,否则

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇C++入门实战-通讯录管理系统 下一篇二、驱动

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目