[操作系统概念]第六部分——内存管理(1)

内存管理

  • 为了让进程只访问自己的内存空间,有两种类型的寄存器:基地址寄存器和界限寄存器保存一个进程使用内存的开始地址和地址长度,这两个寄存器内容的修改是内核的特殊命令,只能在内核模式调用,也就是说用户程序不能修改,只有操作系统可以。

  • 用户程序的生成步骤:

    1. 编译时间:源程序首先被编译生成目标模块
    2. 加载时间:然后与其他模块链接在一起,成为加载模块,系统库加载入模块中,生成二进制数据
    3. 执行时间:最后动态链接的系统库在程序要执行是动态链接到二进制内存镜像中
  • 内存绑定:进程执行的时候,需要将自身放入内存中,至于各种数据如何放入内存,有三种地址绑定的方式

    1. 编译时绑定:在编译时就知道进程在内存中的地址,这样的代码段会生成绝对代码。代码的地址都是定死的。如果开始地址发生变化,需要重新编译。
    2. 加载时绑定:如果在编译时不能确定代码的地址,则编译器会生成可重定位代码,代码和地址的绑定会在加载时在执行
    3. 执行时绑定:如果进程在执行时会从一个内存段移到另一个内存段,那么地址绑定需要等到执行时才可以进行,这种绑定需要特殊硬件支持
  • 逻辑地址与物理地址:
    逻辑地址是CPU计算使用的地址,物理地址是实际内存中每个单元对应的地址。对于编译时绑定和加载时绑定,会生成相同的逻辑地址和物理地址,而执行时绑定会产生不同的逻辑地址和物理地址//这段并不是很懂

如果物理地址和逻辑地址不同的话需要建立二者的映射关系,可以使用基地址寄存器,一般逻辑地址范围是0~max,则物理地址的范围是R+0~R+max(R代表基地址)。

  • 动态加载:一个程序并不是所有代码都需要执行的,可以通过先把不需要的代码放入硬盘,需要时交换如内存使用的方式,节省内存空间,这样的方式叫做动态加载。

  • 动态链接库:
    在加载时间,程序需要的第三方模块,系统库会一起加载,合并生成二进制数据,如果多个程序使用一样的第三方模块或者系统库则需要打包多分相同的代码,这样的做法会造成代码重复浪费内存空间。这时可以使用动态链接,动态加载的模块不合并到程序的二进制数据中,而是在程序中预留存根,使用时会通过存根,确认当前内存中是否有要使用的代码,有的话直接使用,没有的话则加载如内存使用。这样可以使一些共有的库只加载一次,可供多个程序使用。

  • 内存交换
    多个进程在内存中执行,内存keen那个不够使用,这时优先级低的京城可以先交换出内存,保存到快速磁盘等缓存中暂存,然后通过CPU调度待进程需要执行时交换入内存。

内存分配

连续内存分配:将一大块内存分配给一个进程使用

通过将内存分区,一个分区供一个进程使用,这种固定分区的方法已经不再使用,转而使用可变分区的方案。
在可变分区的方案中,内存不划分固定的区,操作系统维护一个表记录每一个进程使用的内存区间。内存中可用的空闲区域被成为“孔”,刚开始,整个内存都是一个大孔,进程执行被分配一块内存,之后由于进程执行所需内存不同、耗时不同,内存就形成了使用中、空闲不再连续的,有若干个孔,孔大小不一的状态。
在可变分区的内存分配方案中,如何为进程分配合适的“孔”是一个问题,这里提出三种分配方式:
1. 最佳适应:搜索所有孔,将孔大小刚刚大于进程所需的内存大小的空。
2. 首次适应:搜索孔,将第一个大小满足的孔分配给进程
3. 最差适应:每次分配当前最大的孔给进程
上述三种份分配方案,最佳适应和首次适应对内存的使用率难分伯仲,且都好于最差适应。此外,最佳适应和首次适应都有 外部碎片问题 ,最差适应有 内部碎片问题

碎片

碎片是指大小较小,进程难以利用的内存片段,这些空间很容易被浪费掉,并且维护困难。外部碎片是指在所分配的孔之外的碎片,存在于几个进程占有的内存块之间,;内部碎片是指在所分配的孔内的碎片,是因为虽然进程分配到了可用的内存,但是不会使用分配到的所有空间而存在的空间浪费。
* 解决方法:一种是紧缩,通过合并内存,移动进程使用的内存块实现,但是这并不都可行,因为有些程序使用静态地址,那么就不可以变更内存。第二种方式是允许进程使用不连续的内存空间,这种思路下有 分页分段 两种实现技术。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值