马轩OS笔记—第七章 内存管理

第七章 内存管理

内存管理是对内存进行划分以适应多进程共同运行。

7.1内存管理的需求

重定位:把虚拟地址映射到实际地址上。当程序执行的时候,处理器硬件和操作系统软件必须能够把程序代码中的储存器访问转化为实际的储存器地址,以反映程序在贮存的当前位置。

内存保护:进程意外的其他进程中的程序不能未经授权地访问该进程中的内存单元。内存保护是由处理器(硬件来实现的)。

共享:任何保护机制必须具有一定的灵活性,以允许多个进程同时访问主存的同一部分。

逻辑组织:计算机系统中的主存总是被组织成线性地址空间。

物理组织:计算机内存至少被组织成两级别,策划那我给主存和辅存。主存提供快速的访问,主存具有易失性,不能提供用具存储。辅存,比主存慢而且便宜,它通常是非易失性。因此,大容量的辅存可以用于长期存储程序和数据,而较小的主存则用于保存当前使用的程序和数据。

7.2内存分区(固定分区、动态分区)

7.2.1固定分区

大小相等分区:

难点:1.程序可能太大而不能放到一个分区内。2.主存的利用效率十分低。任何程序即使很小,都需要占据一个完整的分区。(这些问题都可以通过大小不等的固定分区来解决)

大小不等分区:这样做可以使每个分区内部浪费的时间减少。

这种情况下的,两种排队模型:1.所有的程序都在一个队列中。2.需要每种大小类型的内存单独拍一个队伍

虽然大小不等的分区给固定分区带来了一定的灵活性,但是还是存在不足

  • 分区的数目在系统中限制了活动进程的数目,

  • 由于分区的大小是在系统生成阶段事先设定的,因而小作业不能有效的利用分区空间(内部碎片问题)。

7.2.2动态分区

分区的长度和数目是可变的。当进程被封装进主存时,给它分配与所需空间相等的存储空间。但是动态存储的活动也存在问题,就是当分配一段时间之后在内存上,就有一小段一小段的未被分配的区域,这样的问题就是外部碎片问题。

空闲分区的组织形式,

  • 储存分块表,此时,存在以下缺点——表长不固定,管理困难,分配空间时需要查找整个表
  • 已分/空闲分区表:虽然分成两个表加快了查找速度,但是仍存在表空间难以确定的问题。
  • 空闲存储块表:在空闲分区的起始部分开辟出来一个单元,存放一个链表指针和该分区的大小,链表指针指向下一个空闲分区。

内存的分配和回收

  • 当某一个作业完成释放所占分区时候,系统应该进行回收,在可变分区中,应该检查回收区域内存前后空闲分区是否相连,如空闲则进行合并,形成一个较大的空闲区,并对相应的链表指针进行修改,若不相邻,应将空闲区插入到空闲区链表的适当位置。
  • 动态分区方法在最开始的时候非常好,但是之后就会在内存中出现许多小的空洞。随着时间的推移,内存中产生越来越多的碎片,内存利用率随之下降。这种情况就被称为外部碎片。
  • 克服外部碎片的方法就是“紧缩”:操作系统不时的移动进程,使进程占用的空间连续,并且所有空闲空间连成一片。内存移动是一个十分费时的事情,内存移动也会伴随着动态重定位。

7.2.3重定位

压缩技术总是导致程序可能会转移到不同的分区中,因此需要重新定位地址。地址重定位又称为地址转换。

  • 每一个内存空间对应一个编号,该编号可以唯一标识一个储存单位,称为村内地址。
  • 程序经过汇编之后或者编译之后形成目标程序,每个目标程序都是以0位基址进行编址的。这样的地址称为逻辑地址(物理地址)。
  • 逻辑空间中每条指令的地址和指令中要访问的操作数地址称为逻辑地址(相对地址)。

地址重定位分为两类:

  • 静态重定位:在装入一个作业时,把作业中的指令地址全部转换为绝对地址,在作业执行的时候就不许进行地址转换了。
  • 动态地址重定位:程序执行过程中,在CPU访问内存之前,将要访问的程序或数据地址转换为内存地址。

VR是程序虚地址寄存器,BR是基地址寄存器,MA是内存地址。当程序处于运行态的时候,有一个特殊的处理器寄存器被称为基址寄存器,还有一个界限寄存器表示程序的的终止位置。它们可以用来内存保护。

地址:

  • 逻辑地址:与当前数据与内存中的物理分配地址无关的访问地址,在执行对内存的访问之前必须把它转换为物理内存。
  • 相对地址:相对某个已知点的地址。
  • 物理地址:内存中的绝对地址。

7.3简单分页

固定分区管理(内部碎片)–》可变分区管理(外部碎片)–》紧缩(系统开销比较大)

因此我们使用另外一种方法来解决外部碎片问题:分页存储管理允许程序的储存空间不连续,即可以把一程序分散地放在内存块中,它既不需要移动内存中原有的信息,有解决了外部碎片问题,提高了内存利用率。

我们将内存划分为大小固定的相等的块,并且块相对比较小,每个进程也被分为同样大小的小块,那么进程中称为页的块制定到内存中称为帧或页帧的可用块。在本节中我们将会看到,在内存中为每个进程浪费的空间仅仅是进程最后一页的一小部分形成的内部碎片,没有任何外部碎片。

分页存储管理的基本原理:

内存空间分块–内存划分为大小相等的存储块,称为帧、物理页或者实页。

逻辑空间分页–作业空间划分为与内存块相等大小的逻辑块,称为页、逻辑页或者虚页。

内存分配原则:

系统以块为单位把内存非给作业或者进程,并且一个进程的若干个页可以分别装入物理上不相邻的内存块中,只要也表中能表示出来就好了。

页表:需要一个表格来表指出各个进程的各页放在主存的那个页架中—页表。

页表的作业就是实现从页面到物理块号的地址映射。

映射过程:

  1. 页号:即逻辑地址最左面的n位。(因为每一个页面的大小都是2的指数倍,所以很容易理解后面几位是表示页内偏移量,前几位是表示页面数。)
  2. 按照上述的页号来查找页表,参照哦哦该进程页表中相应的帧号。
  3. 该帧的起始物理位置为k*2^n。利用帧号与逻辑地址的‘页面偏移量’部分,构成物理地址,然后访问主存。
  4. 物理地址不需要计算,他可以通过简单的把偏移量添加在帧号码的后面。

因此我们可以发现通过页表,我们可以实现虚页到实页的转换。

7.4简单分段

人们希望按照程序的模块来分‘段’,然后按‘段’进行主存分配。

段—-一组逻辑信息的集合,如子程序、数组或数据区。

  • 进程作业的逻辑地址空间:主要概念:段名(程序员自己指定)、段号(也称内部段名,从0开始,OS指定)以及内地址(现行的,从0开始编址)逻辑地址就可以表示为(S,W)。 S为段号,W为段内地址。
  • 程序的地址结构

image-20191107000648665

  • 内存分配:以段为单位,一个进程的各段可不相临(跟分页十分相似)

  • 段表:一般包含以下信息–段号、段长、在主存中的起始位置。
  • 段的地址转化:
    • 首先提取出来逻辑地址的段号
    • 然后对用段表提取来段号对应的段的起始物理地址
    • 然后提取出来,页内偏移量
    • 物理位置为业内偏移量+起始物理位置。

四种内存管理方法的总结:

image-20191107001214261

image-20191107001240118