内存管理:OS对内存的划分和动态分配
来自王道2024版
主要功能:
-
内存空间的分配于回收:
由OS完成,不用人为分配,提高编程效率 -
地址转换:
将逻辑地址转换为物理地址 -
内存空间的扩容:
利用虚拟存储技术或自动覆盖技术,从逻辑上扩充内存 -
内存共享:
运行多个进程访问内存的同一部分 -
存储保护:
保证各道作业在各自的存储空间内运行,互不干扰
一、程序的链接与装入
将程序和数据装入内存所需步骤:
-
编译:由编译程序将源代码编译成若干目标模块
-
链接:由链接程序将目标模块及所需的库函数链接在一起,形成完整的装入模块
链接方式:
-
静态链接:在运行前→将目标模块和所需的库函数链接成装入模块
1)修改相对地址
2)变换外部调用符号 -
装入时动态链接:在装入内存时,边装入边链接
1)便于修改和更新,便于实现共享 -
运行时动态链接:程序执行中需要该目标模块时链接
1)加快程序装入过程,节省大量内存空间
-
-
装入:由装入程序将装入模块装入内存运行
装入方式:
-
绝对装入:按装入模块中的地址,装入内存
1)只适用于单道程序
2)编译程序产生绝对地址(也可以程序员赋予),逻辑地址与实际内存地址相同,不用修改地址 -
可重定位装入(静态重定位):根据内存当前状况,将装入模块装入内存的适合位置
1)适用于多道程序
2)在装入时修改目标程序的指令和数据地址(重定向)
3)在进程装入时一次性完成地址变换
4)装入时分配要求的全部空间,并在运行时不能移动和再申请空间 -
动态运行时装入(动态重定位):将装入模块装入内存后不立即地址转换,推迟到程序真正执行时进行
1)装入内存后所有地址都是相对地址,需要重定位寄存器支持
2)可以将程序分配到不连续的存储区
3)只需部分代码即可运行,需要时再动态分配内存
4)利于程序共享
-
二、逻辑地址与物理地址
相对地址(逻辑地址):编译后每个目标模块都从0号单元开始编址
-
链接时按顺序将各个模块相对地址构成统一从0开始的逻辑地址空间(虚拟地址空间)
-
运行时,看到和使用的都是逻辑地址,不同进程可以有相同的逻辑地址
物理地址:内存中物理单元的集合→地址转换的最终地址
-
运行时,执行指令和访问数据需要通过物理地址从主存中获取
-
将装入模块装入内存时,必须通过地址变换将逻辑地址→物理地址(地址重定位)
-
逻辑地址通过内存管理部件(MMU)转为物理地址,通过页表映射到物理内存,页表由OS维护并被处理器引用
三、进程的内存映像
一个程序调入内存运行时,构成了进程的内存映像
内存映像要素:
-
代码段:可以被多个进程共享的只读二进制代码
-
数据段:程序运行时加工处理的对象,包括全局变量和静态变量
-
PCB:存放在系统区
-
堆:存放动态分配的变量,malloc动态分配空间
-
栈:用来实现函数调用,调用函数,栈增长;函数返回,栈收缩
堆和栈可以再运行时动态扩展和收缩
四、内存保护
确保每个进程都有自己的内存空间。内存分配前,保护OS不受用户进程影响,同时保护用户进程不受其他用户进程影响
方法:
1. 在CPU中设置一对上、下限寄存器,存放用户作业在主存中的下限和上限地址,每当CPU访问一个地址时,分别与两个寄存器的值相比,判断有无越界
2. 采用重定位寄存器(基地址寄存器)和界地址寄存器(限长寄存器)来实现。
1)重定位寄存器存放最小的物理地址值,界地址寄存器存放逻辑地址的最大值。
2)内存管理机构动态地将逻辑地址与界地址寄存器比较,若未越界,则加上重定位寄存器地值后映射成物理地址,再交给内存单元
加载重定位寄存器和界地址寄存器必须使用**特权指令**,**内核**操作,不允许用户程序修改
五、内存共享
只有只读的区域才可以共享
可重入代码:纯代码,允许多个进程同时访问单不允许被任何进程修改的代码
内存共享的实现方式:→
六、内存分配与回收
单一连续分配→固定分区分配→动态分区分配
连续分配→离散分配(页式存储管理)/分段存储管理