内存管理概念

本节介绍操作系统内存管理的不同方式,可能在选择题中考察,也可能在大题中作为知识点考察。

内存管理的基本概念

共享内存(Shared Memory)是多个进程共享的内存区域。它是最快的IPC(进程间通信)机制之一,因为进程直接读写内存,无需进入内核态。但是,因为多个进程可以同时访问这些内存,所以可能需要某种同步机制(如信号量)来防止竞态条件。

  • 内存保护

内存保护是现代操作系统中的一个核心功能,用于防止一个进程访问另一个进程的内存空间。这不仅保障了系统的稳定性,而且提高了安全性,因为它可以防止恶意软件损害其他进程或篡改其数据。

可以通过如下机制实现内存保护机制:

  1. 分段与分页:
    • 分段: 内存被划分为不同的段,每个段都有其起始地址和长度。段常常用于表示高级的数据结构,如函数或对象。
    • 分页: 内存被划分为固定大小的页面,例如4KB。操作系统为每个进程维护一个页表,来映射其虚拟地址到物理地址。
  2. 访问权限: 每个段或页面都有与之相关的访问权限。例如,一个页面可能被标记为只读,这意味着任何尝试写入该页面的操作都会引发一个异常。
  3. 隔离: 由于每个进程都有其独立的地址空间,所以一个进程不能直接访问另一个进程的内存。这为每个进程提供了一种形式的隔离,确保了一个出错的进程不会影响其他进程。

连续分配管理方式

1. 单一连续分配

内存在此方式下分为系统区和用户区,系统区仅供操作系统使用,通常在低地址部分;在用户区内存中,仅有一道用户程序,即整个内存的用户空间都由该程序独占。

这种方式的优点是简单、无外部碎片,无需进行内存保护,因为内存中永远只有一道程序。缺点是只能用于单用户、单任务的操作系统中,存储器的利用率极低。

2. 固定分区分配

固定分区分配是最简单的一种多道程序存储管理方式,它将用户内存空间划分为若干固定大小的区域,每个分区只装入一道作业。当有空闲分区时,便可再从外存的后备作业队列中选择适当大小的作业装入该内存,如此循环。

为了方便内存分配,通常将分区按大小排队,并为之建立一张分区说明表,其中各表项包含每个分区的起始地址、大小和状态。当有用户程序需要装入时,便检索该表,以找到合适的分区基于分配并将其状态设置为“已分配”;未找到合适分区时,则拒绝为给程序分配内存。

partition number
start address/KB
size/KB
status
1
20
20
allocated
2
32
32
allocated
3
64
64
not allocated
4
128
128
allocated

3. 动态分区分配

Kernel Memory
Kernel Memory
Process 1
Memory
Process 1...
Free Memory
Free Memory
Process 2
Memory
Process 2...
Free Memory
Free Memory
Process 3
Memory
Process 3...
Free Memory
Free Memory
Text is not SVG - cannot display

内存空间中的空闲区域可能大小不一,且分布在内存中不同的位置。当进程申请一块新的内存时,必须从已有的空闲空间中选出一块分配给进程。动态分区的分配策略包含以下几种算法:

  • First Fit(首次适应)
    • 当需要分配内存时,它不从内存的开始位置开始,而是从上一次分配内存的地方开始。
  • Next Fit(临近适应)
    • 这种策略与首次适应相似,但当需要分配内存时,它不从内存的开始位置开始,而是从上一次分配内存的地方开始。
  • Best Fit(最佳适应)
    • 为了满足内存请求,最佳适应策略会在所有可用的内存块中查找并选择最小的、但足够大的内存块(申请内存/内存块大小最大),这种策略的目标是最大限度地减少浪费的内存空间。。
  • Worst Fit(最坏适应)
    • 与最佳适应的目标相反,其思想是留下最大的连续空闲区域,希望这样可以满足后续的大请求。

页式管理

段式管理

段式内存管理是一种内存组织方法,它将程序的不同部分(例如代码、数据和堆栈)划分为不同的段(segments)。每个段在物理内存中可以不连续,但在逻辑上都被视为连续的。这种方法的主要优点是它允许更为灵活的内存使用,并有助于提供更好的保护和共享机制。

段定义

  • 每个段都有一个明确的角色,例如代码段、数据段或堆栈段。
  • 每个段都有一个起始地址和长度。
  • 段内的地址是连续的,但不同段之间的地址可以不连续。

段表

  • 段表是一种数据结构,用于存储每个段的基地址(在物理内存中的起始地址)和限制(段的长度或末尾地址)。
  • 当一个程序需要访问其内存段时,会使用段号和段内偏移作为地址。这个地址被称为逻辑地址或段地址。
  • 逻辑地址通过段表转换为物理地址。

地址转换

  • 为了从逻辑地址获取物理地址,首先需要从逻辑地址中提取段号,然后使用段号在段表中查找相应的基地址和限制。
  • 然后,检查逻辑地址中的偏移量是否小于该段的限制。如果偏移量超出限制,则产生段越界错误。
  • 如果偏移量有效,则将偏移量加到段的基地址上,得到物理地址。

段页式管理

段页式管理是一种将段式内存管理与分页式内存管理相结合的策略。它结合了两者的优势,旨在提供灵活性和减少内存碎片。在段页式管理中,程序首先被划分为逻辑上的段,然后每个段进一步被划分为固定大小的页。

segment size
segment start address
segment table
*
*
*
*
*
*
page table