操作系统-非连续内存管理

71 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

虚拟内存

操作系统引入了虚拟内存,进程持有的虚拟地址会通过 CPU 芯片中的内存管理单元(MMU)的映射关系,来转换变成物理地址,然后再通过物理地址访问内存

有两种映射方式:

  • 内存分段
  • 内存分页

内存分段

于是程序可由若干个逻辑分段组成的,如可由代码分段、数据分段、栈段、堆段组成。不同的段是有不同的属性的,所以就用分段(Segmentation)的形式把这些段分离出来。

因为分段后各段是离散的,为了保证程序能正常运行,就必须能从物理内存中找到各个逻辑段的存放位置,实现这个功能的是段表

段表

  • 段表里面保存的是这个段的基地址
  • 如果段内偏移量是合法的,就将段基地址加上段内偏移量得到物理内存地址。

分段的办法很好,优点是解决了程序本身不需要关心具体的物理内存地址的问题,但它缺点是:

  • 第一个就是外部 内存碎片的问题。
  • 第二个就是内存交换的效率低的问题。(硬盘的读写速度比内存慢太多了,每一次内存交换,我们都需要把一大段连续的内存数据写到硬盘上。 )

内存分页

分页是把整个虚拟和物理内存空间切成一段段固定尺寸的大小。这样一个连续并且尺寸固定的内存空间,我们叫页(Page)。在 Linux 下,每一页的大小为 4KB。为什么要分页?为了更合理的分配进程在内存中存放

虚拟地址与物理地址之间通过页表来映射


寻址过程:

  • 简单来说就是:重定位寄存器(保存着该模块的物理地址)+ 目标的逻辑地址

分页的优势:

采用了分页,那么释放的内存都是以页为单位释放的,也就不会产生无法给进程使用的小内存。

如果内存空间不够,操作系统会把其他正在运行的进程中的「最近没被使用」的内存页面给释放掉,也就是暂时写在硬盘上,称为换出(Swap Out)。

一旦需要的时候,再加载进来,称为换入(Swap In)。所以,一次性写入磁盘的也只有少数的一个页或者几个页(不会出现一整个段的磁盘读写),不会花太多时间,内存交换的效率就相对比较高。

这种简单的页表有空间上的缺陷,页表必须连续存放,当页表过大时,需要占用很多连续的页框。