计算机操作系统(三)内存管理

160 阅读8分钟

第三章、内存管理机制

1. 内存管理主要是干嘛的?

  1. 负责内存的分配与回收(malloc 函数:申请内存,free 函数:释放内存)

  2. 地址转换也就是将逻辑地址转换成相应的物理地址等功能也是操作系统内存管理做的事情(CPU 中含有一个被称为 内存管理单元(Memory Management Unit, MMU) 的硬件)

2. 分段式管理内存?

分段管理就是将一个程序按照逻辑单元分成多个程序段,每一个段使用自己单独的虚拟地址空间。例如,对于编译器来说,我们可以给其5个段,占用5个虚拟地址空间,并分配一段连续的地址空间(段内要求连续,段间不要求连续,因此整个作业的地址空间是二维的)。其逻辑地址由段号S与段内偏移量W两部分组成

段式存储管理也需要一个表来存储逻辑空间到物理空间的映射,这个就是段表。

image.png

优点:

  1. 按照程序的逻辑关系进行分段,段大小可以改变

缺点:

  1. 存在外部碎片问题,一个段必须全部加载到内存。
  2. 为了解决外部内存碎片,就需要进行内存交换
  • 外部内存碎片,也就是产生了多个不连续的小物理内存,导致新的程序无法被装载;
  • 内部内存碎片,程序所有的内存都被装载到了物理内存,但是这个程序有部分的内存可能并不是很常使用,这也会导致内存的浪费

对于多进程的系统来说,用分段的方式,内存碎片是很容易产生的,产生了内存碎片,那不得不重新 Swap 内存区域,这个过程会产生性能瓶颈。因为硬盘的访问速度要比内存慢太多了,每一次内存交换,我们都需要把一大段连续的内存数据写到硬盘上。所以,如果内存交换的时候,交换的是一个占内存空间很大的程序,这样整个机器都会显得卡顿。

3. 分页式管理内存?

分页是把整个虚拟和物理内存空间切成一段段固定尺寸的大小。这样一个连续并且尺寸固定的内存空间,我们叫Page)。在 Linux 下,每一页的大小为 4KB

虚拟地址与物理地址之间通过页表来映射,页表存储在内存管理单元(MMU)中

由于内存空间都是预先划分好的,也就不会像分段会产生间隙非常小的内存,这正是分段会产生内存碎片的原因。而采用了分页,那么释放的内存都是以页为单位释放的,也就不会产生无法给进程使用的小内存。

如果内存空间不够,操作系统会把其他正在运行的进程中的「最近没被使用」的内存页面给释放掉,也就是暂时写在硬盘上,称为换出(Swap Out)。一旦需要的时候,再加载进来,称为换入(Swap In)。所以,一次性写入磁盘的也只有少数的一个页或者几个页,不会花太多时间,内存交换的效率就相对比较高

分页的方式使得我们在加载程序的时候,不再需要一次性都把程序加载到物理内存中。我们完全可以在进行虚拟内存和物理内存的页之间的映射之后,并不真的把页加载到物理内存里,而是只有在程序运行中,需要用到对应虚拟内存页里面的指令和数据时,再加载到物理内存里面去

4. 什么是虚拟内存?

一个游戏十几G,物理内存只有4G,那么这个游戏是怎么运行起来的呢?

  1. 虚拟内存是操作系统管理内存的一种方式,它使得应用程序认为自己拥有连续的完整的可用内存(一段连续的虚拟内存空间),但实际上是被分隔成多个物理内存碎片,还有部分是存储在外部的磁盘存储器中,目的是让程序拥有更大的可用内存。
  2. 每个进程都有自己的地址空间,地址空间的页映射到物理内存中,进程运行时并不需要地址空间的页全部加载到物理内存中,而是部分加载,当使用到了一个不在物理内存中的页时,会发生页面置换算法,将该页置换到内存中
  3. 进程持有的虚拟地址会通过 CPU 芯片中的内存管理单元(MMU)的映射关系,来转换变成物理地址,然后再通过物理地址访问内存

局部性原理:局部性原理指的是CPU访问存储器时,无论是存取指令还是存取数据,所访问的存储单元都趋于聚集在一个较小的连续区域中

虚拟地址空间和物理地址空间的映射关系:虚拟地址 = 页号+页内偏移

页号可用作为页表的索引。页表包含了物理页每页所在物理内存的地址,这个基地址+页内偏移就能找到物理地址了。 总结一下,对于一个内存地址转换,其实就是这样三个步骤:

  • 把虚拟内存地址,切分成页号和偏移量;
  • 根据页号,从页表里面,查询对应的物理页号;
  • 直接拿物理页号,加上前面的偏移量,就得到了物理内存地址。

页表太多会不会太复杂了 --- 多级页表。

5.分段式和分页式的区别?

两者都采用离散分配方式,且都要通过地址映射机构来实现地址变换

区别:

  1. 页是信息的物理单位,分页是为了实现非连续分配,以便解决内存碎片问题, 提高内存的利用率。或者说,分页仅仅是由于系统管理的需要而不是用户的需要。段则是信息的逻辑单位,分段的目的是为了能更好地满足用户的需要。
  2. 页的大小固定且由系统决定,由系统把逻辑地址划分为页号和页内地址两部分,是由机器硬件实现的,因而在系统中只能有一种大小的页面;而段的长度却不固定,决定于用户所编写的程序,通常由编译程序在对源程序进行编译时,根据信息的性质来划分。
  3. 分页的作业地址空间是一维的,即单一的线性地址空间,程序员只需利用一个记忆符,即可表示一个地址;而分段的作业地址空间则是二维的,程序员在标识一个地址时,既需给出段名,又需给出段内地址。

6. 段页式管理内存?

段页式内存管理实现的方式:

  • 先将程序划分为多个有逻辑意义的段,也就是前面提到的分段机制;
  • 接着再把每个段划分为多个页,也就是对分段划分出来的连续空间,再划分固定大小的页;

用于段页式地址变换的数据结构是每一个程序一张段表,每个段又建立一张页表,段表中的地址是页表的起始地址,而页表中的地址则为某页的物理页号。

段页式地址变换中要得到物理地址须经过三次内存访问:

  • 第一次访问段表,得到页表起始地址;
  • 第二次访问页表,得到物理页号;
  • 第三次将物理页号与页内位移组合,得到物理地址。

可用软、硬件相结合的方法实现段页式地址变换,这样虽然增加了硬件成本和系统开销,但提高了内存的利用率,这样既拥有分段系统的共享和保护,又拥有分页系统的虚拟内存功能。

7. 常见的页面置换算法有哪些?

程序运行过程中,都是采用虚拟内存的方式,如果要访问的页面不在内存中,就会发生缺页中断将该页调入内存中,如果内存中也没有空闲空间的话,就必须从内存中调出一个页面放入磁盘中来腾出空间,如何选择被淘汰的页面就是页面算法,这个算法的主要目标是使页面置换频率最低(也可以说缺页率最低)。

  1. 最佳算法:所选择的被换出的页面将是最长时间内不再被访问,通常可以保证获得最低的缺页率,但是是一种理论上的算法,因为无法知道一个页面多长时间不再被访问。
  2. 先进先出:选择换出的页面是最先进入的页面
  3. 最近最少使用算法(LRU):
  4. 最不经常使用算法(LFU):
  5. 时钟置换算法(CLOCK):

image.png