分段与分页

重定位

一个程序要加入到内存后才能开始运行,我们需要在内存中找一块空闲区域来存放程序,那么对于程序中所指明的地址,我们需要进行重定位操作,将逻辑物理地址转化成实际的物理地址。
重定位的时机:

  1. 编译时:需要在编译时就知道哪些物理内存是空闲的(很不灵活),一般嵌入式系统可以用。
  2. 载入时:在程序载入到内存时改变程序中的地址,但是一旦载入到内存中就不能在动了,但是程序在载入后都会需要移动(swap交换)。
  3. 运行时重定位:每执行一条指令都从逻辑地址算出物理地址,每个进程的基地址都存放在PCB中,执行指令时第一步先从PCB中取出这个基地址,通过基地址+逻辑地址来进行地址翻译。
分段

程序由若干个段组成:主程序,变量集,函数库,动态数组,栈,每个段有各自的特点以及用途,对于每个段来说其开始地址都是0,而不是把所有段组成一个段从0开始。这样的话可以让用户独立的考虑每个段(从程序员的角度来看)
因此我们可以不用将整个程序集中处理放到内存中,而是可以各段分别放入内存中(比如栈不够时,分段处理可以只移动栈段的位置)。因此我们需要通过一个进程段表来存储不同段对应的基址(操作系统对应的段表->GDT表)。每个进程都有各自的LDT表,LDT表也对应一个内存中的段,所以先从GDT表中找到LDT表,然后通过LDT表可以找到每个段的基址。
内存的分割:将程序分为多个段后,我们需要分割内存,将各个段放入内存中。

  1. 固定分区:操作系统初始化时将内存等分K个分区,因为段的大小有大有小,所以不太合适.
  2. 可变分区:用空闲分区表以及已分配分区表来进行管理,当一个段需要使用内存时,根据空闲分区表来给其分配内存。
    内存分段的问题:当没有足够大的空闲分区可分配时(内存碎片),需要进行空闲分区的合并,非常耗费时间,而且上层用户此时是无法执行的。
分页。

为了解决分段的问题,可以将物理内存等分成页,针对每个段内存的请求,系统将一页一页的分配给这个段,此时一个段最多浪费一页的空间。需要用一个页表来存储每个段的页号所对应物理内存中的哪个页框。
在这里插入图片描述
在这里插入图片描述

多级页表

为了提高内存空间利用率,页的大小应该尽可能的小,可是页小了之后,页表就会变大。
实际上大部分的逻辑地址是不会用到的,可是如果对于没有使用的空间如果不在页表中占位,我们每次访问地址都需要遍历一遍页表,效率太低。
我们可以使用多级页表,将多个页表组合成一个章节,每次查询先找到所在章节,再找需要的页表。对于不需要的章节在页表中也进行占位处理,不过节省了许多空间(因为不用每个页都进行占位,而是一个章占一个位置)。

快表

多级页表解决了空间存储的问题,可增加了访存的次数,我们使用快表来增加访问速度,每次访存先进行快表的访问(速度非常快),如果没查到再去多级页表中进行查询,并且更新快表内容。

段页结合

从程序员的角度来看,程序是多个不同段组成的,而从物理内存来看,是希望把内存分成多个页的。我们给每个程序的段分到虚拟内存中,建立虚拟内存到物理内存的映射来实现段页结合(段面向用户,页面向硬件)。
从用户角度来看,每个进程都有属于他的一整块空间,当进行访问时,通过将虚拟地址转化为物理地址来达成访问。

载入过程:将内存分为多个相同长度的页,将程序分成多个段,每一段都分成若干个页映射到物理内存中,查找数据时先通过段表找到虚拟地址,然后通过页表找到对应的物理地址。
在这里插入图片描述

fork时的内存分配

根据不同的操作系统实现有不同的方法,下面只是其中一种可实现的方式。
我们首先假设每个进程的虚拟空间不相互重叠,在进行fork时,父子进程可以先公用同一物理内存,只需要建立子进程所需要的页表关联到同一物理内存。在有写操作进行时子进程才进行物理内存的分配->写时复制

内存换入换出

在用户角度来看,其实际使用的是一大块完整的空间,可是有时候物理内存是没有那么大的空间的,那么在访问时对未在物理内存中的数据需要从磁盘换入。
当请求数据时,根据逻辑地址(段号+偏移)查找段表找到虚拟地址(页号+偏移),再通过查页表找到实际的物理地址,而有时候内存中是没有该数据的,那么此时就会产生一个缺页中断,执行页错误处理程序,从内存中找到空闲物理页,将数据从磁盘中读入内存,修改页表,这样再次执行时便能够成功找到该数据。
在这里插入图片描述
内存空间是有限的,当选择页面换入时,如果并不能获得新的页,就需要选择一页进行淘汰换出到磁盘。
比较常见的方法:FIFO,MIN算法(将来最远使用的页淘汰),LRU算法(将最近最长一段时间没有使用的页淘汰),Clock算法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值