操作系统内存管理方式主要两种,不同的管理方式,寻址的实现是不同的:
- 内存分段:将进程的虚拟地址空间划分为多个不同大小的段,每个段对应一个逻辑单位,如代码段、数据段、堆段和栈段。每个段的大小可以根据需要进行调整,使得不同段可以按需分配和释放内存。虚拟内存分段的优点是可以更好地管理不同类型的数据,但是由于段的大小不一致,容易产生外部碎片。
- 内存分页:将进程的虚拟地址空间划分为固定大小的页,同时将物理内存也划分为相同大小的页框。通过页表将虚拟地址映射到物理地址,并且可以按需加载和释放页。虚拟内存分页的优点是可以更好地利用物理内存空间,但是可能会产生内部碎片。
分段的寻址方式
分段机制下的虚拟地址由两部分组成,段选择因子和段内偏移量。
段选择因子和段内偏移量:
- 段选择子就保存在段寄存器里面。段选择子里面最重要的是段号,用作段表的索引。段表里面保存的是这个段的基地址、段的界限和特权等级等。
- 虚拟地址中的段内偏移量应该位于 0 和段界限之间,如果段内偏移量是合法的,就将段基地址加上段内偏移量得到物理内存地址。
在上面,知道了虚拟地址是通过段表与物理地址进行映射的,分段机制会把程序的虚拟地址分成 4 个段,每个段在段表中有一个项,在这一项找到段的基地址,再加上偏移量,于是就能找到物理内存中的地址,如下图:
如果要访问段 3 中偏移量 500 的虚拟地址,我们可以计算出物理地址为,段 3 基地址 7000 + 偏移量 500 = 7500。
分段的办法很好,解决了程序本身不需要关心具体的物理内存地址的问题,但它也有一些不足之处:
- 第一个就是内存碎片的问题。
- 第二个就是内存交换的效率低的问题。
分页的寻址方式
虚拟地址与物理地址之间通过页表来映射,如下图:
页表是存储在内存里的,内存管理单元 (MMU)就做将虚拟内存地址转换成物理地址的工作。
而当进程访问的虚拟地址在页表中查不到时,系统会产生一个缺页异常,进入系统内核空间分配物理内存、更新进程页表,最后再返回用户空间,恢复进程的运行。
在分页机制下,虚拟地址分为两部分,页号和页内偏移。
页号作为页表的索引,页表包含物理页每页所在物理内存的基地址,这个基地址与页内偏移的组合就形成了物理内存地址,见下图。
总结一下,对于一个内存地址转换,其实就是这样三个步骤:
- 把虚拟内存地址,切分成页号和偏移量;
- 根据页号,从页表里面,查询对应的物理页号;
- 直接拿物理页号,加上前面的偏移量,就得到了物理内存地址。
下面举个例子,虚拟内存中的页通过页表映射为了物理内存中的页,如下图:
© 版权声明
本站文章由不念博客原创,未经允许严禁转载!
THE END