计算机操作系统教程——分区存储管理


1 分区管理基本原理

  给每一个内存中的进程划分一块适当大小的存储区,以连续存储个进程的程序和数据,是各进程得以并发执行。按分区的时机,分区管理可以分为固定分区和动态分区两种方法。

1.1 固定分区法

  固定分区法就是把内存固定划分为若干个大小不等的区域。分区划分的原理有一般系统操作员或操作系统决定。
  系统对内存的管理和控制通过数据结构——分区说明表进行,分区说明表说明个分区号、分区大小、起始地址和是否空闲区。

1.2 动态分区法

  在作业的处理过程中进行分区建立,其大小可随作业或进程对内存的要求而改变。


2 分区的分配与回收

2.1 固定分区时的分配与回收

  固定分区时的分配与回收不会涉及到空闲区的合并,相对来说比较简单。

2.2 动态分区是的分配与回收

  动态分区是的分配与回收主要解决3个问题:

  1. 对于请求中的要求内存长度,从可用表或自由链中寻找合适的空闲区分配程序。
  2. 分配空闲区之后,更新可用表或自由链。
  3. 进程或作业释放内存资源时,和相邻的空闲去进行链接合并,更新可用表或自由链。

2.2.1 最先适应算法(first fit algorithm)

  可用表或自由链按起始地址递增的次序排列,一旦找到大于或等于所要求内存长度的分区,则结束搜索。

2.2.2 最佳适应算法(best fit algorithm)

  从小到大的次序组成空闲区可用表或自由链,从表头开始查找,当找到第一个满足要求的空闲区是,停止查找。

2.2.3 最坏适应算法(worst fit algorithm)

  空闲区按其大小递减的顺序组成空闲区可用表或自由链。当用户作业或进程申请一个空闲区是,先检查空闲区可用表或自由链的第一个空闲可用区的大小是否大于或等于所要求的的内存长度,若可用表或自由链的第一个项长度小于所要求的的,则分配失败,否则从空闲区可用表或自由链中分配相应的存储空间给用户,然后修改空闲区可用表或自由链。

2.3 动态分区时的回收与拼接

  在将一个空闲区插入可用表或自由链是,该空闲区和上下相邻区的关系是下述四关系之一:

  1. 上下相邻分区都是空闲区
  2. 上相邻区是空闲区
  3. 下相邻区是空闲区
  4. 上下相邻区都不是空闲区

2.4 其中分配算法的比较

2.4.1 搜索速度

  从搜索速度上看,最先适应算法具有最佳性能。尽管最佳适应算法或最坏适应算法看上去能很快的找到一个最适合的或最大的空闲区,但后两种算法都要求首先把大小不同的空闲区按其大小进行排队,这实际上是对所有空闲区进行一次搜索。

2.4.2 释放速度

  从回收过程来看,最先适应算法也是最佳的。因为使用最先适应算法回收某一空闲区时,无论被释放区是否与空闲区相邻,都不用改变该去在可用表或自由链中的位置,只需要修改其大小或起始地址。而最佳适应算法和最坏适应算法都必须重新调整该区的位置。

2.4.3 空闲区的利用

  最先适应算法尽可能地利用了低地址空间,从而保证高地址有较大的空闲区来放置要求内存较多的进程或作业。
  反过来,最佳适应法找到的空闲区是最佳的,也就是说,用最佳适应法找到的空闲区或者是正好等于用户请求的大小或者是能满足用户要求的最小空闲区。不过,尽管最佳适应法能选出最适合用户要求的可用空闲区,但这样做在某些情况下并不一定能提高内存的利用率(有些小空间可能可不到利用)。
  最坏适应算法正是基于不留下碎片空闲区这一出发点的,它选择最大的空闲区来满足用户要求,以期分配后的剩余部分仍能进行再分配。


3 有关分区管理其他问题的讨论

3.1 关于虚存的实现

  利用分区式管理,也同样存在每个用户可以自由编程的虚拟空间。但是,分区式管理方式无法实现那种用户进程所需内存容量只受内存和外存容量之和限制的虚拟存储器。事实上,如果不采用内存扩充技术,每个用户进程所需内存容量是受到分区大小限制的。

3.2 关于内存扩充

  由于分区式管理时各用户进程或作业所要求的内存容量受到分区大小的限制,如果不采用内存扩充技术,将会极大地限制分区式管理技术的使用。在分区式管理中,可以使用覆盖或交换技术来扩充内存。

3.3 关于地址变换和内存保护

  静态地址重定位和动态地址重定位技术都可用来完成分区式内存管理的地址变换。显然,动态分区时分区大小不固定,而空闲区的拼接会移动内存中的程序和数据,因此,使用静态定制重定位的方法来完成动态分区时的地址变换是不妥当的。
  在进行动态地址重定位是,每个分区需要一对硬件寄存器的支持,即基址寄存器和限长寄存器,分别用来存放作业或进程在内存分区的起始地址和长度。这一对硬件寄存器除了完成动态地址重定位的功能之外,还具有保护内存中数据和程序的功能。
  保护键法也可用来存放作业或进程在内存分区的起始地址和长度。

3.4 分区管理的主要优缺点

3.4.1 优点

  1. 实现了多个作业或进程对内存的共享,有助于多道程序设计,从而提高了系统的资源利用率。
  2. 该方法要求的硬件支持少,管理算法简单,因而实现容易。

3.4.2 缺点

  1. 内存利用率不高。和单一连续分配算法一样,内存可能含有从未用过的信息。而且,还存在着严重的碎小空闲区(碎片)不能利用的问题,这更进一步影响了内存的利用率。
  2. 作业或进程的大小受分区大小控制,除非配合采用覆盖和交换技术。
  3. 无法实现各分区间的信息共享。

4 Reference

[1] 张尧学. 计算机操作系统教程[M]. 清华大学出版社, 2018.

  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
抱歉,我不是一个可以提供代码的程序,但是我可以向您提供一些关于可变分区存储管理的基本信息。 可变分区存储管理是一种常见的存储管理方法,它允许进程动态地分配和释放内存。在可变分区存储管理中,物理内存被划分为多个不同大小的分区,每个分区可以被分配给一个进程。当一个进程需要内存时,它可以向操作系统申请一个或多个分区。当进程不再需要这些分区时,它可以将它们释放回操作系统。 在实现可变分区存储管理时,需要考虑以下几个方面: 1. 分区的大小和数量,以及进程如何分配和释放分区。 2. 如何处理碎片化问题,即已分配的分区之间的未使用的空间。 3. 如何处理内存不足的情况。 在具体实现时,可以使用链表或位图等数据结构来管理可用的内存分区。当进程申请内存时,可以遍历链表或位图来查找可用的分区。当进程释放内存时,可以将该分区标记为空闲,并将其合并到相邻的空闲分区中。 以下是可变分区存储管理的示例代码(C语言): ```c #include <stdio.h> #include <stdlib.h> // 内存块结构体 typedef struct block { int start; // 起始地址 int length; // 长度 int is_free; // 是否空闲 struct block* next; // 下一个内存块 } Block; // 内存块链表结构体 typedef struct block_list { Block* head; // 头节点 Block* tail; // 尾节点 } BlockList; // 初始化内存块链表 void init_block_list(BlockList* list) { list->head = NULL; list->tail = NULL; } // 添加内存块 void add_block(BlockList* list, int start, int length, int is_free) { Block* block = (Block*)malloc(sizeof(Block)); block->start = start; block->length = length; block->is_free = is_free; block->next = NULL; if (list->head == NULL) { list->head = block; list->tail = block; } else { list->tail->next = block; list->tail = block; } } // 从内存块链表中删除内存块 void remove_block(BlockList* list, Block* block) { if (block == list->head) { list->head = block->next; } else { Block* prev = list->head; while (prev != NULL && prev->next != block) { prev = prev->next; } if (prev != NULL) { prev->next = block->next; } } if (block == list->tail) { list->tail = NULL; } free(block); } // 在内存块链表中查找指定长度的空闲块 Block* find_free_block(BlockList* list, int length) { Block* block = list->head; while (block != NULL) { if (block->is_free && block->length >= length) { return block; } block = block->next; } return NULL; } // 分配内存 int allocate_memory(BlockList* list, int length) { Block* block = find_free_block(list, length); if (block == NULL) { return -1; // 内存不足 } if (block->length == length) { block->is_free = 0; } else { Block* new_block = (Block*)malloc(sizeof(Block)); new_block->start = block->start + length; new_block->length = block->length - length; new_block->is_free = 1; new_block->next = block->next; block->length = length; block->is_free = 0; block->next = new_block; } return block->start; } // 释放内存 void release_memory(BlockList* list, int start) { Block* block = list->head; while (block != NULL) { if (block->start == start) { block->is_free = 1; // 合并空闲块 if (block->next != NULL && block->next->is_free) { block->length += block->next->length; remove_block(list, block->next); } if (block != list->head && block->is_free && block->next != NULL && block->next->is_free) { Block* prev = list->head; while (prev != NULL && prev->next != block) { prev = prev->next; } if (prev != NULL) { prev->length += block->length; prev->next = block->next; free(block); block = prev->next; } } break; } block = block->next; } } // 打印内存块链表 void print_block_list(BlockList* list) { printf("Memory blocks:\n"); Block* block = list->head; while (block != NULL) { printf("[%d, %d] %s\n", block->start, block->length, block->is_free ? "free" : "allocated"); block = block->next; } } int main() { BlockList list; init_block_list(&list); add_block(&list, 0, 100, 1); add_block(&list, 100, 50, 1); print_block_list(&list); int addr1 = allocate_memory(&list, 30); printf("Allocate memory at address %d.\n", addr1); print_block_list(&list); int addr2 = allocate_memory(&list, 70); printf("Allocate memory at address %d.\n", addr2); print_block_list(&list); release_memory(&list, addr1); printf("Release memory at address %d.\n", addr1); print_block_list(&list); release_memory(&list, addr2); printf("Release memory at address %d.\n", addr2); print_block_list(&list); return 0; } ``` 该示例代码演示了如何使用链表来管理内存块,并实现了分配和释放内存的功能。具体实现可以根据自己的需求进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值