操作系统——存储器管理
程序的装入和链接
用户程序想要在系统中运行,必须先将他装入内存,然后再将其转变为一个可执行的程序,步骤:
编译——>链接——>装入
程序的装入:
- 绝对装入方式:(只适用于单道程序环境)
在编译的时候就知道了程序驻留在内存的什么位置了;装入模块装入内存后,程序中的逻辑地址与实际内存地址完全相同,不用修改程序和数据的地址 - 可重定位装入方式:
在装入时对目标程序中指令和数据的修改过程称为重定位。地址变换在装入时一次完成,以后不再改变,称为静态重定位。
如下图:地址1000装入后,地址就变为了1000+10000=11000了。
- 动态运行时的装入方式:
动态运行时的装入程序,在把装入模块装入内存后,并不立即把装入模块中的相对地址转换为绝对地址,而是把这种地址转换推迟到程序真正要执行时才进行。因此,装入内存后的所有地址都仍是相对地址。
程序的链接
根据链接时间的不同,把链接分成三种:
-
静态链接:在程序运行前,将目标模块及所需的库函数链接成一个完整的装配模块,以后不再拆开。
-
装入时动态链接:指将用户源程序编译后所得的一组目标模块,在装入内存时,采用边装入边链接的链接方式。
-
运行时动态链接:指对某些目标模块的链接,是在程序执行中需要该目标模块时,才对它进行链接。
将目标模块装配成装入模块时需解决的两个问题:
(1) 对相对地址进行修改
(2) 变换外部调用符号
连续分配存储器管理方式
单一连续分配
最简单的一种存储管理方式,但只能用于单用户、单任务的操作系统中。
采用这种存储管理方式时,可把内存分为系统区和用户区两部分,系统区仅提供给OS使用,通常放在内存低址部分,用户区是指除系统区以外的全部内存空间,提供给用户使用。
固定分区分配
- 原理
将内存用户空间划分为若干个固定大小的区域,在每个分区中只装入一道作业,这样把用户空间划分为几个分区,便允许有几道作业并发执行。当有一空闲分区时,便可以再从外存的后备作业队列中,选择一个适当大小的作业装入该分区,当该作业结束时,可再从后备作业队列中找出另一作业调入该分区。 - 划分分区的方法
可用两种方法将内存的用户空间划分为若干个固定大小的分区:
(1) 分区大小相等:缺乏灵活性,用于一台计算机控制多个相同对象的场合
(2) 分区大小不等:把内存区划分成含有多个较小的分区、适量的中等分区及少量的大分区,可根据程序的大小为之分配适当的分区。 - 实现
为便于内存分配,通常将分区按大小进行排队,并为之建立一张分区使用表,其中各表项包括每个分区的起始地址、大小及状态(是否已分配)。
当有一用户程序要装入时,由内存分配程序检索该表,从中找出一个能满足要求的、尚未分配的分区,将之分配给该程序,然后将该表项中的状态置为“已分配”;若未找到大小足够的分区,则拒绝为该用户程序分配内存。
动态分区分配
- 原理
动态分区分配是根据进程的实际需要,动态地为之分配内存空间。作业装入内存时,把可用内存分出一个连续区域给作业,且分区的大小正好适合作业大小的需要。分区的大小和个数依装入作业的需要而定。 - 实现
在实现过程中涉及如下问题:
分区分配中的数据结构
分区分配算法
分区分配及回收操作
1) 分区分配中的数据结构
(1)空闲分区