第 8 章 内存管理策略

Posted astonc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第 8 章 内存管理策略相关的知识,希望对你有一定的参考价值。

  为了实现性能改进,应将多个进程保存在内存中,也就是说必须共享内存。

8.1 背景

  内存是现代计算机运行的核心。内存由一个很大的字节数组来组成,每个字节都有各自的地址。

8.1.1 基础硬件

  CPU可以直接访问的通用存储只有内存和处理器内置的寄存器。

  每个进程都有一个独立的内存空间,可以保护进程不会互相影响。

  • 基地址寄存器(base register):最小的合法的物理内存地址。
  • 界限地址寄存器(limit register):指定了范围的大小。

  合法范围为(base, base + limit)register

  内存空间保护的实现是通过CPU硬件对在用户模式下产生的地址与寄存器的地址进行比较来完成的。

  只有操作系统可以通过特殊的特权指令,才能加载基地址寄存器和界限地址寄存器。不允许用户程序修改它们。

8.1.2 地址绑定

  源程序中的地址通常是用符号表示的,编译器通常将这些符号地址绑定到可重定位的地址。链接程序或加载程序再将这些可重定位的地址绑定到绝对地址。每次绑定都是从一个地址空间到另一个地址空间的映射。

  通常,指令和数据绑定到存储器地址可在沿途任何一步中进行:

  • 编译时
  • 加载时
  • 执行时

8.1.3 逻辑地址空间和物理地址空间

  CPU生成的地址通常称为逻辑地址,而内存单元看到的地址(即加载到内存地址寄存器)通常称为物理地址。

  编译时和加载时的地址绑定方法生成相同的逻辑地址和物理地址。

  由程序生成的所有逻辑地址的集合称为逻辑地址空间,这些逻辑地址对应的所有物理地址的集合称为物理地址空间。

  执行时地址绑定,逻辑地址空间和物理地址空间是不同的。

  从虚拟地址到物理地址的运行时的映射是有内存管理单元(Memory-Management Unit,MMU)的硬件设备完成的。基地址寄存器在这里被称为重定位寄存器。用户进程所生产的地址在送交内存之前,都将加上重定位寄存器的值。

  用户程序不会看到真实的物理地址。

8.1.4 动态加载

  一个程序只有在被调用时才会加载。所有程序都以重定位加载格式保存到磁盘上。

8.2 交换

  进程必须在内存中以便执行。不过,进程可以暂时从内存中交换到备份存储,当再次执行时再调回到内存。

  交换有可能让所有进程的总的物理地址空间超过真实系统的物理地址就,从而增加了系统的多道程序程度。

8.3 连续内存分配

  早期方法,每个进程位于一个连续的内存区域,与包含下一个进程的内存相连。

8.3.1 内存保护

  重定位寄存器+限界寄存器

8.3.2 内存分配

  最简单的方法就是将内存分成多个固定大小的分区,每个分区只包含一个进程。因此,多道程序的程度受限于分区数。

  可变分区方案:操作系统有一个表,用于记录哪些内存可用和哪些内存已用。开始,所有内存都可用于用户进程,因此可用作为一个大块的可用内存,称为孔。

  动态存储分配问题,从一组可用孔中选择一个空闲孔的最常用的方法包括:

  • 首次适应,分配首个足够大的孔。
  • 最优适应,分配最小的足够大的孔。
  • 最差适应,分配最大的孔。

8.3.3 碎片

  外部碎片,分区之间。解决方法之一是紧缩,移动内存内容,将所有空闲空间合并成一块。另一种方法是运行进程的逻辑地址空间是不连续的。

  内部碎片,分区内部,分区大于进程的大小。

8.4 分段

基本方法

  逻辑地址空间由一组段构成,每个段都有 <段号, 段偏移>。

分段硬件

  实际物理地址是一维的,所以要将逻辑地址二维映射到一维上。

  

以上是关于第 8 章 内存管理策略的主要内容,如果未能解决你的问题,请参考以下文章

第三部分:内存管理

RTX——第18章 内存管理

第6章 内存管理

《python解释器源码剖析》第17章--python的内存管理与垃圾回收

STM32H7第22章 ThreadX动态内存管理

STM32F429第22章 ThreadX动态内存管理