理解操作系统之存储管理

3,311 阅读10分钟

本文是介绍操作系统存储管理的入门级文章,旨在介绍操作系统中存储管理的一般内容,本文主要围绕以下话题展开。

  • 计算器系统中的存储结构
  • 程序的链接和装入的概念
  • 程序存储空间的分配
    1. 连续存储空间分配
    2. 离散存储空间分配(分页存储,分段存储,段页式存储)
  • 虚拟存储器
    1. 请求分页存储
    2. 请求分段存储
    3. 置换算法

一丶计算机系统中的存储结构

计算机系统中的存储结构
上图中描述了计算机系统中的一般存储结构,从左往右存储资源的价格越来越便宜,但是存取的速度越来越贵。本文研究的存储管理指的主存管理以及少部分磁盘和主存之间的交互。

  • CPU寄存器,这是最昂贵的存储资源,里面一般缓存了些极其重要且频繁使用的数据。比如地址变换表的基地址等信息。
  • 高速缓存,是为了提高CPU资源利用率而设计的存储结构,存放的时最近使用以及将来会使用的数据。越靠近CPU侧存取速度越快,存储价格越高。
  • 主存,这是最主要的存储区域。运行中的程序(进程)都是被加载到主存中的。
  • 磁盘,这是生活中最接触的存取区域,一般存放可执行文件,资源文件,配置文件等。IO操作就是指对磁盘进行的读写操作。很多场景下IO操作是系统性能的瓶颈

二丶程序的链接和装入

  1. 装入

    这是一个比较容易理解的概念,将位于硬盘上的代码加载至内存中的过程即为装入。在装入的过程中,存在一个转换的过程。该过程将程序代码中的逻辑地址转换物理内存中绝对地址。不同的地址转换方式对应三种不同装入方式

  • 绝对装入

    在程序代码编写的过程就确定了存储的物理地址。此时逻辑地址和物理地址保持一致。在现在操作系统中不会采用这种方式

  • 可重定位装入

    在程序加载到内存地址中是,其可以存储到内存的任意位置。物理地址 = 逻辑地址(相对地址) + 物理内存加载处的起始地址。 可重定位的装入方式比绝对装入灵活多了,但是其存储地址在刚载入内存后就固定了,后续不可以移动存储位置。在现在操作系统中也不使用这种方式

  • 运行时装入

    目前主流的装入方式,其在程序加载到内存时,不会将逻辑地址转换物理地址,仅仅在程序代码被执行时,才将逻辑地址转换为物理地址。 运行时装入,允许程序在在读内存后,依旧能够在存储空间中移动。能满足内存整理等场景的要求。

  1. 链接

    链接也是一个比较易懂的概念,和装入的过程颇为相似。程序在经过编译之后,将形成多个目标模块,将这多个目标模块组合成一个整体的过程即为链接。根据这些目标模块组合的不同时机,链接分为以下三类

  • 静态链接

    在程序运行之间,就将像目标模块以及库函数合=链接成一个整体模块。

  • 装入时链接

    在装入目标模块的时候,一边装入一边链接

  • 动态链接

    在使用到相关程序逻辑的时候,开始链接。

三丶程序存储空间的分配

在程序执行完链接和装入过程后,位于硬盘上的代码就将载入内存中。此处必须要为程序分配其所需要的存储空间。依据分配存储空间是否连续这一特点,可将存储空间的分配分为连续分配以及离散分配

  1. 连续存储空间分配

    • 单一连续存储分配

      该种方法适用于单用户,单任务的操作系统。其将主内存分为系统内存和工作内存。系统内存负责载入操作系统等内容。工作内存仅载入需执行的任务,每个被加载的任务将独占内存。系统内存和工作内存之间相互独立。

    • 固定存储分配

      该方法适用于适用于多任务操作系统。其将主内存分为多个大小相等的子内存区域,当存在任务加载需求的时候,将任务加载去子内存区域。该方法采用的固定分区,灵活性不够。不能解决分区过大导致的内存碎片的问题,也不能解决分区过小导致无法载入大作业的问题。(也可以将内存固定划分为不等的子内存区域,又称为不等分区固定分配)

    • 动态存储空间分配

      在任务加载进内存时,依据任务所需内存大小实现按需分配。动态存储空间分配,看似解决了内存碎片问题,实际上并不是这样的。在动态存储空间分配时,多次内存分配操作,会产生一系列地址不联系,大小各异的内存空间。当这些内存空间被回收后,将退化成不等分区的固定存储分配。

    • 可重定位的分区分配

      该存储方式,在动态存储空间分配上添加了内存整理功能。若当前内存空间不能满足任务所需内存空间时,其会将已分配的内存空间全部移动,使未分配的内存空间形成一片连续的地址空间。该种方法则要求程序的装入方式是动态装入

    上述介绍的四种存储空间分配方法被称为连续的分配是因为其不能分割作业存储。只能将作业存储在一块连续内存空间中,并不能将作为划分成更小的单位进行分块存储。

  2. 离散存储空间分配

    离散存储空间分配是指,其能将任务分割成更小的存储单位。分割后的存储单位连续存储,而存储单位与存储单位之间并不要求连续。通过将任务拆分进行存储的方法,能极大的提高存储空间的利用率。

    • 页式存储空间分配

      这里将定义为一个固定大小的存储单位。在将任务载入内存时,一个完整的任务可以被划分成多页。每页独立的存储到内存空间中,内存空间中存储位置可用物理页号描述。每页的存储是连续,页与页之间的存储并不是连续的,而是离散存储的。 为了建立任务的地址与物理空间地址之间的联系。在内存表中将建立页表,完成页号到物理号的映射

    页表

    • 段式存储空间分配

      段式存储的方法和页式存储的方法手段都是一致。将任务以**段为存储单位,将任务分成多段进而离散存储。**在内存中同样维护了一张段表。段表和页表结构是一致的。

      段表
      那么页式存储和段式存储这两者的差别究竟何在呢? 以下是页式存储和段式存储的差别

      • 页是信息的物理单位,分页式为了减少内存碎片,提高内存利用率而提出的。段是信息的逻辑单位,它包含一组完成的逻辑意义,其不仅能提高内存利用率,而且在方便编程,信息共享,信息保护等方面均有好处。
      • 页的大小是有操作系统固定设计的,在系统中页的大小是固定且唯一的。段长度并不是固定的,取决于用户所编写的程序,通常由编译程序在对源程序进行编译时,根据信息的性质决定。
    • 段页式存储空间分配

      该存储方式实际上是,分页存储和分段存储的组合。先将任务按照段进行划分,然后每段按照分页的方式进行存储,即为段页式存储。下文将比较分页存储,分段存储,以及段页式存储内存地址的变化

      • 分页存储地址(页号:页内偏移地址)
      • 分段存储地址(段号:段内偏移地址)
      • 段页式存储(段号段内偏移页号:页内偏移地址)

四丶虚拟存储器

虚拟存储器是现在操作系统广泛使用的一种存储方式,虚拟存储能在不对物理内存扩容的基础上,保证能够运行更多更大的内存任务。虚拟存储器和常规存储器的不同之处在于,虚拟存储器不要求你任务一次性全部载入内存,而是按需载入内存。并且能在内存空间受限时,将闲置的内存作业调出内存,这种将内存作业调出内存的过程称为置换,完成置换过程的方式则称为置换算法。在上述过程中,不将作业一次性完全载入内存,显然是建立在分页存储或者分段存储的基础上,下文对这两种情况分别介绍

  • 请求分页存储

    请求分页存储具有两点内容需要理解:

    1. 分页加载,按需加载

      请求分页存储将任务以页为单位进行划分,在载入内存时,并不将全部页面载入。而是将部分必须的页面载入内存,其他的页面在程序运行中,若使用则按需载入内存。

    2. 分页置换

      在内存空间紧张时,会将程序中某些使用或者近期不在使用的页面,从内存置换到磁盘中去。

    在请求分页存储中,内存中维护的页表不再是简单的页号到内存物理号之间的映射了。其页表结构一般如下:

    • 页号,这个字段代表分页顺序
    • 物理块号,这个字段代表,该页在内存中的位置
    • 状态位P,该状态位用来标识该页是否载入内存,true代表载入内存,false代表未载入内存
    • 访问字段,该状态位是统计状态位,可以用来记录该页最近被访问的次数
    • 修改位,该位用来标识,该页载入到内存后是否被修改过了。若内存中修改过后,其置换到外存时,需要回写回去。如果没有修改过,那么其置换到外存时,无须回写回去。
    • 外存地址,该位存储该也在外存中的地址。一般来说,在载入内存后,外存上依旧会留有一一份拷贝信息。
  • 请求分段存储

    请求分段存储与请求分页存储及其相似。唯一的区别便是,载入和置换的单位从转换到了

  • 置换算法

    置换算法,在虚拟存储器中是非常重要的内容。在虚拟存储器设计理念中,当内存资源紧张的时候,会依据置换算法将内存中的页面置换到外存中。此处介绍两种置换算法

    1. LRU(Least Recently used,最近最久使用算法)

      最近最久未使用算法,在页面项中添加了访问时间字段T,记录最近一次访问到目前过去的时间。在需要进行页面置换时候,将T最大的页面置换出去。

    2. LFU(Least Frequently used,最少使用算法)

      最少使用算法,在页面项中添加了访问频率字段F,计算最近一段时间内该页面被访问的频率。在需要进行页面置换时候,将F最小的页面置换出去