内存管理

一、内存管理功能

           1、内存的分配和回收:当作业或进程创建后系统会为他们分配内存空间,当结束后内存空间也会被回收。

           2、地址转换:将程序中的逻辑地址转换成内存中的物理地址。

           3、内存空间的扩充:利用虚拟存储技术或自动覆盖技术,从逻辑上扩充内存。

           4、存储保护:保护每个作业在自己的内存空间运行,互不干扰。

二、连续内存分配

、        1、连续内存分配:给程序分配一块连续内存区域。

            2、内存碎片:内存上一些没有被分配利用的区域   

                        内部碎片:某个程序分配的内存没有充分利用。是否产生取决于分配算法,比如分配的内存大小是否需要取整。

                        外部碎片:被分配的内存区域之间的空闲区域。

            3、碎片整理:通过调整进程占用的内存区域位置来减少或避免分区碎片

            4、碎片紧凑:通过移动分配给进程的内存区域,以合并外部碎片。要求运行的程序都可以动态重定位。

        2.1、单一连续分配   

                       分配方法 :将内存去划分为系统区和用户区,系统区为操作系统使用,剩下的用户区给一个进程或作业使用。       

                       特点: 操作简单、没有外部碎片,适合单道处理系统。但是会有大量的内部碎片浪费资源,存储效率低。

                       固定分区分配:

                       分配方法:

                       1、分区大小相等:将内存的用户区分成大小相等的区域,每个内存只能申请一块区域;

                       2、分区大小不等:将内存的用户区分成大小不等的区域,分配原则是多个较小的区域,适量中等大小区域,少量的最大分区。每个进程根据大小只能申请一块区域。

                       特点:固定分区虽然没有外部碎片,但是会造成大量的内部碎片。分区大小相等缺乏灵活性,大的进程可能放不进去;分区大小不等可能会造成大量的内部碎片,利用率极低。   

                      分配算法:

                      首次适应算法:进程进入内存之后从头开始查找第一个适合自己大小的分区。空间分区就是按照地址递增的顺序排列。算法开销小,回收后放到原位置就好,综合看这个算法性能最好。

                      最佳适应算法:将分区从小到大排列(容量递增),找到最适合自己的分区,这样会有更大的分区被保留下来,满足别的进程需要。但是算法开销大,每次进程消亡产生新的区域后需要重新排序。并且当使用多次后会产生很多外部碎片。

                      最坏适应算法:将分区从大到小排列(容量递减),进程每次都找最大的区域来使用,可以减少难以利用的外部碎片。但是大分区很快就被用完了,大的进程可能会有饥饿的现象。算法开销也比较大。

                      邻近适应算法:空间分区按照地址递增的顺序进行排列,是由首次适应演变而来,进程每次寻找空间,从上一次查找的地址以后开始查找(不同于首次适应,首次适应每次从头开始开始查找)。算法开销小,大的分区也会很快被用完。

                      注意:以上进程使用空间不会产生内部碎片,当进程大小为60MB的进程找到了一块100MB的空间,它只会使用60MB,剩下的40MB会给别的进程。

                      动态分区分配:

                      分配方法:

                      不会先划分内存区域,当进程进入内存的时候才会根据进程大小动态的为其建立分区,使分区大小刚好适合进程需要。

                      特点:在开始是很好的,进程依次按照顺序存入内存,但是运行久了以后随着进程的消亡,会出现很多成段的内存空间,时间越来越长就会导致很多不可利用的外部碎片,降低内存的利用率。这时需要分配算法来解决。

三、非连续内存分配

           可以将一个进程分散装入内存分区。根据分区的大小是否固定可以分成分页存储管理(固定)与分段存储管理(不固定),为了两者的缺点,还可以二者混用成段页式存储管理。再根据进程运行作业时是否将作业的全部代码装入内存,又分为基本分页存储管理(全部装入内存)和请求分页存储管理(非一次全装入内存)。

           段式内存管理

              

           段指一类地址空间,一个段就是一个连续的内存块,若干个段组成程序的逻辑地址空间。

           每个段由0到最大的线性地址序列构成。各个段的长度可以是0到某个允许的最大值之间的一个数。不同的段的长度可以不同(通常情况下也都不一样),段的长度在运行期间可以动态改变,比如push数据时,堆栈段的长度增加,pop时会减少,段也可以被装满,但是通常情况下段的长度很大,这种情况很少发生。

          段式存储管理下的逻辑地址组成格式为(s,o),s为段号,o为段内偏移量,段号和对应内存中的物理起始地址由段表记录。寻址时,先根据段号到段表中查到物理起始地址(基址),然后加上偏移量,得到最终的物理地址。

                 

         恢复进程运行环境,从PCB中找到段表寄存器

         根据逻辑地址得到段号、段内地址

         将段号与段表长度比较,判断段号是否越界,产生越界中断

         查询段表,找到对应的段表项,段表项存放的地址为段表起始地址+段号*段表项长度(因为为了节省内存空间,可以参略段表中的段号,那么计算段表项的起始地址就可以用这种方法)

         对段内地址W进行检查,是否超过段长。如果超越就产生中断

         根据段的基址和和段内地址得到物理地址

         访问目标内存单元

         页式内存管理

         页式存储管理的寻址方式和段式管理类似,逻辑地址格式为(p,o),表示页中的地址,其中p表示页号,o表示偏移量,物理地址格式为(f,o),表示页帧中的地址,其中f表示页帧号,o表示偏移量,页偏移量和页帧偏移量是相等的。

         页和页帧的对应的关系使用页表来管理。寻址时首先根据页号找到页表中对应的页帧号,然后用得到的页帧号与偏移量组成实际的物理地址。

             

         地址变换机制及变化过程

         

         在系统中会设置一个页表寄存器(PTR),用来储存页表在内存中的起始地址F和页表长度M

         根据逻辑地址计算出页号和业内偏移量

         判断页号是否越界

         查询页表找到页号对应的页表项,确定页面的内存块号(第一次访存,因为页表在内存中)

         用内存块号和业内偏移量的到物理地址

         访问内存目标单元(第二次访存)

         具有快表(TLB)的地址变换机构

         

         CPU给出逻辑地址后,由硬件进行地址转换,将页号送入高速缓存寄存器,并将次页号与快表中的页号做比较

         如果找到,直接从快表去除该页对应的页框号,与地址结构的地址偏移量计算出物理地址访存

         如果没有找到,再去慢表中找,然后如上访存,之后将这个页表项加入到快表中。注意有的系统为了节省时间,会在快表中找与在慢表中找同时进行,这样可以节约系统时间。

         两级页表:

         一级页表,页表必须是连续存放的,因此当页面很大的时候,需要占用很多个连续的叶匡没必要让整个页表常驻内存,所以引出二级页表。

         步骤:

         按照地址结构将逻辑地址拆分成三部分(一级页号、二级页号、页内偏移量)

         从PCB中读取页目录表起始地址,再根据一级页号查页目录表,找到下一级页表在内存中的存放位置

         根据二级也好查表,找到最想访问的内存块号

         结合页内偏移量得到物理地址

         段页式内存管理

         背景:由于分段与分页各有利弊,页式存储提高内存利用率,段式存储反应程序逻辑结构有利于共享数据,所以可以结合二者来组成新的内存管理方式。

         概念:首先将进程根据逻辑结构划分成若干个逻辑段,每个段都有自己的段号,然后将这些段划分成若干个大小固定的页。这样对内存空间的管理依然和分页式管理相似,将内存分成和页面大小相同的存储块,对内存分配一存储块为单位。

         逻辑地址结构:逻辑地址结构由段号S(决定每个进程的段数)、页号P(决定每段的页数)、页内偏移量W(页面的大小和内存块的大小)组成。

         

         根据逻辑地址得到段号、页号、页内偏移量

         将段号S与段表长度比较,判断段号是否越界

         查询段表,找到对应的段表项,段表项存放的地址为段表起始地址+段号*段表项长度(因为为了节省内存空间,可以参略段表中的段号,那么计算段表项的起始地址就可以用这种方法)(第一次访存)

         将页号与页表长度比较,检查页号是否越界

         根据页表存放块号、页号查询页表,找到对应的页表项(第二次访存)

         根据内存块号、页内偏移量得到最终的物理地址

         访问目标内存单元(第三次访存)

         注意:1、段表寄存器和页表寄存器作用有两个,一是在段表或页表中寻址,二是判断是否越界;2、在一个进程中段表只能有一个,页表可以有很多个。3、分段是可见的,分页是不可见的所以段页式管理结构是二维的。4、*这里也可以引入快表机构,用段号和页号作为查询快表的关键字,如果快表命中就只需要访存一次

四、虚拟内存

           背景

           传统的内存管理方式具有一次性(作业必须一次性的装入内存,其实每次运行的只是一小部分)和驻留性(作业被装入内存后会一直驻留在内存中直到所有的作业结束)。这两个特性导致了内存空间存储效率极低,所以引入了虚拟内存的概念。

           局部性原理

           局部性原理分为时间局部性与空间局部性。 时间局部性:程序中的一条指令一旦执行,不久后改指令还可能再次被执行。产生时间局部性的原因是程序中存在大量的循环操作。 空间局部性:一旦程序访问了某个存储单元,在不久后,其附近的存储单元也会被访问。因为指令的顺序通常是顺序存储、顺序执行的。数据的存储也是向量、数组、表等形式

           概念

           基于局部性原理,在程序装入内存时,只会将程序的一部分装入内存,就可以启动程序。在程序执行过程中如果所需要的信息不在内存中,可以由操纵系统将需要的那一部分数据再调入内存。如果操作系统暂时不适用某些内容,可以将其调到外存上,从而腾出空间供别的作业使用。以上就称为虚拟存储器。

           特性

           多次性:是指作业在运行的过程中不是一次性全部调入内存,而是分成多次调入内存。

           对换性:是指作业在运行过程中不需要一直存放在内存中,需要的作业从外存换入,不需要的可以暂时换出

           虚拟性:从逻辑上扩充了内存的容量,使用户看到内存容量很大的程序却很顺利的运行在很小的内存上。

           实现

           虚拟内存的实现需要建立在离散分配的内存管理方式上 主要实现方式:

           请求分页存储管理

           请求分段存储管理

           请求段页式存储管理

           硬件支持:

           一定的内存与外存空间

           页表机制或者段表机制

           中断机制,当用户要访问的程序调入内存需要中断

           地址变换机制,逻辑地址转换成物理地址

           请求分页

           请求分页管理方式时间里在分页管理方式的基础之上,请求分页系统中只需要将当前需要的一部分页面装入内存中作业就可以正常运行,当访问的页面不在内存中的时候,可以采用换入将外存中的页面换入内存。

           页表机制

           为了发现和处理页面不在内存中的情况,引入来了页表机制。

           页表机制组成:

           页号:页的编号

           内存块号(物理块号):储存物理地址内存中的块号

           状态位P:用来表示该页是否已经调入内存

           访问字段A:记录页面指标。记录本页在一段时间内被访问的次数,或者记录本页进入内存多长时间未被访问。共页面置换算法换出页面时访问。

           修改位M:标记本页在调入内存后有没有被修改过,因为修改过的页面是要重新写入内存的,在选择换出时可以选择这种页面。

           外存地址:用来表示该页在外存中的地址。

           缺页中断机构

           每当内存需要访问的页面不在内存中的时候,系统就会产生一个缺页中断,请求操作系统将缺少的页面调入内存。这个时候缺页的进程会发生阻塞,也为它缺少某一资源。

           缺页中断过程:保护CPU环境、分析中断原因、装入缺页中断处理程序、回复CPU环境

           与一般中断区别:

           在指令的执行期间,不是一条指令执行完成后产生中断,它是属于内中断。

           一条指令的执行过程中可能会发生多次中断。因为进程需要申请缺少的资源

          地址变换机构

          

          页面置换算法

          页面置换算法主要是决哪一页被换入,哪一页被换出。

          最佳置换算法(OPT)

          思想:最佳置换算法是淘汰以后不会使用的,或者是在长时间内不在访问的页面,以保证获得最低的缺页率。

          特点:这个算法是很难实现的,由于很难预估那个页面是以后不会访问的。

          注意:最长时间不访问和以后访问次数最小是两个概念。

          先进先出页面置换算法(FIFO)

          思想:淘汰最早进入内存的页面,就是在内存中驻留最久的页面。

          特点:这个算法容易实现,但是不符合常理,因为在进程中有的页面会被经常访问到。

          注意:这个算法可能产生换页次数不减反增的现象,称为Belady现象

          最近最久未使用置换算法(LRU)

          思想:选择最近最长时间没有被访问的页面

          特点:性能好,但是需要寄存器和栈的硬件支持,

          时钟置换算法(CLOCK)

          简单的时钟置换算法

          思想:让一个指针循环扫描缓冲区,像时钟转动一样。会给每一页面增加一个附加位,称为使用位。当页面被调入内存的时候和页面被使用后将他的使用位置为1。页面需要替换的时候,指针会扫描每一页的使用位,如果为1,扫描过后置成0;如果为0,就将该页置换出去。如果所有的页面都为1的话,会继续扫描第二遍。

          特点:这个算法的思想其实和最近最久未使用页面置换算法相似,只是这个实现起来更加的方便。

          高级时钟置换算法

          思想:再增加一位,称为修改位(因为被修改过的页面在被替换前一定要重新写回外存,所以这样可以节省时间)。 设使用位为u,修改位为m。

          从指针开始的位置开始扫描,第一轮不对任何数据修改,查找(u=0,m=0)的页面换出

          如果第1步失败,从头开始扫描,查找(u=0,m=1)的换出,如果不是就将每个页面的使用位置成0;

          如果第2步失败,从头开始扫描,查找(u=0,m=0)的页面换出。如果不是就将页面的修改位改成0;

          如果第3步失败,从头开始扫描,查找(u=0,m=0)的页面置换出。

       

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值