当前位置: 首页 > news >正文

内存管理 : 04段页结合的实际内存管理

一、课程核心主题引入

这一讲,我要给大家讲的是真正的内存管理,也就是段和页结合在一起的内存管理方式。之前提到过,我们先学习了分段管理内存的工作原理,知道操作系统采用分段的方式,让用户程序能以分段的结构进行编写;后来又学习了分页管理内存,明白操作系统在管理物理内存时,通过分页机制更高效地利用内存。分段对用户和应用程序友好,分页对物理内存管理高效,所以这两种机制必须结合起来。
在这里插入图片描述

这一讲的关键,就在于探究段和页这两种机制如何结合,以及结合后实际的物理内存管理是什么样的。程序员希望用段来编写程序,物理内存希望用页来进行管理,而操作系统作为中间桥梁,既要让上层用户满意,又要高效管理下层物理内存资源,所以必须将分段和分页两种机制融合。接下来,我先给大家讲讲段页结合的思路,再深入探讨这种结合方式的具体实现。

二、段页结合的思路解析

  1. 回顾分段与分页工作原理
    • 先来回顾一下分段是怎么工作的。想象一下,有一个程序和一块内存,我们在内存中采用分区的方法,根据程序分段的数量划分出相应的区域。比如程序分成两段,就割出两个区域,然后将用户程序中的段和这些区域建立映射,把代码段放在一个区域,数据段放在另一个区域,这样应用程序就放到内存的段中了。
    • 再看看分页的工作方式。物理内存会被打散成一页一页固定大小的片,我们的程序同样也会被打散。假设程序有两个段,将这两个段也打散成若干页,然后把这些页映射到物理内存的空闲页上,分页机制的工作就完成了。
  2. 段页结合的具体方式
    • 现在要把段和页结合起来,该怎么做呢?仔细观察分段和分页的工作过程图,我们可以发现一个巧妙的方法。把程序中的段先映射到一个类似物理内存的地方,但它不是真正的物理内存,只是一个地址空间。这个地址空间可以划分成一块一块的,就像物理内存一样,不过划分出来的只是地址,还不能直接访问真实的物理内存,我们把它叫做虚拟内存

    • 具体来说,从应用程序角度出发,在虚拟内存给定的地址空间上,割出一个区域给程序中的段,这样就实现了对段的支持,段有了对应的映射。但是虚拟内存本身不能直接使用,它只是一个虚拟的地址空间,所以还需要把虚拟内存中的段再分割成固定大小的页,然后将每页映射到物理内存上。经过这两次映射,就形成了既有段又有页的内存管理模式。在这里插入图片描述

    • 从用户的角度看,程序对应到虚拟内存上,感觉就像在使用段,他们不用关心底层的复杂映射过程,只知道自己的程序段在一段地址空间上,并且可以像使用段一样连续地进行寻址访问。而从物理内存的角度,是把虚拟内存中的段映射到物理内存页上,实现了分页管理。通过引入虚拟内存这个概念,完美地将段和页结合在了一起,这就是段页式内存管理的核心轮廓。

三、段页同时存在时的重定位过程

  1. 重定位的必要性
    我们已经知道段页是如何结合工作的了,但要让程序在内存中顺利运行,还需要进行重定位,也就是地址翻译。因为用户发出的逻辑地址,像程序中使用的段号加上段的偏移地址,需要经过转换,才能找到真正的物理地址,这样程序才能在内存中正确地取指执行。

  2. 重定位的具体步骤在这里插入图片描述

    • 当用户发出逻辑地址(段号 + 段偏移)时,首先要根据段表找到一个地址,这个地址是虚拟地址。在只有分段的情况下,这个地址就是物理内存地址,但在段页结合的模式下,它还不是真正的物理地址,只是虚拟内存中的地址。
    • 得到虚拟地址后,操作系统还要根据分页机制再进行一次映射。通过虚拟地址算出页号,再结合页内偏移,组合形成物理地址。最后,操作系统把这个物理地址发送到地址总线上,程序就能访问到真正的物理内存单元,取出数据或执行指令了。整个过程需要经过两层地址翻译,第一层基于分段,第二层基于分页,这样既支持了分段,又支持了分页,用户感觉自己在使用段,而物理内存则按照页的方式进行管理和分配。

四、段页式内存下程序载入内存的过程

  1. 程序载入内存的总体步骤在这里插入图片描述
    在这里插入图片描述

    • 我们的目标是让操作系统管理内存,使用户程序能够放入内存并正常执行。在段页式内存管理下,程序载入内存的过程可以分为几个关键步骤。第一步,要在虚拟内存上割出一段区域,分配给用户程序的代码段、数据段等,然后建立段表,记录虚拟内存区域和程序段的对应关系,这一步相当于“假装”把程序段放入了内存。
    • 第二步,虽然在虚拟内存中有了映射,但程序还没有真正放到物理内存中,所以接下来要在物理内存中找到空闲页,建立页表,将虚拟内存中的区域和物理内存的页关联起来。通过磁盘读写操作,把程序真正载入到物理内存中。
    • 第三步,完成前面的操作后,程序已经在内存中了,但要能正常使用内存,还需要进行重定位,也就是前面讲的地址翻译过程,让程序中的地址能够正确对应到物理内存单元,这样程序就能顺利执行了。
  2. 结合代码分析具体操作(以fork为例)在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    • 我们从fork函数开始分析程序载入内存的过程。fork函数用于创建子进程,在这个过程中会涉及到内存的分配和映射。copy_process函数会进行一系列操作,其中copy_mem函数中的代码实现了关键步骤。

    • set_base等代码用于设置段表,这对应着第一步在虚拟内存上分配区域并建立段表的操作。通过计算,给每个进程分配一定大小的虚拟内存空间(如这里每个进程分配64兆),并将虚拟内存的起始地址赋给段表中的基址,完成对虚拟地址的分割和段表的初始化。在这里插入图片描述

    • 接下来是分配物理内存和建立页表。由于子进程是通过复制父进程创建的,所以在copy_page_tables函数中,子进程可以共用父进程已经分配好的物理内存页,只需要拷贝页表即可。通过一系列代码操作,先确定父进程和子进程的页目录,为子进程分配新的页目录项(如果需要),然后将父进程页表中的内容拷贝到子进程的页表中,并将共享的页设置为只读,同时更新内存使用计数等信息。这样,父子进程就都有了自己的虚拟内存、物理内存,并且段表和页表都已正确建立,程序成功载入内存。
      在这里插入图片描述

五、程序使用内存的过程及多进程地址分离在这里插入图片描述

  1. 程序使用内存的操作
    当操作系统把段表和页表做好后,程序就可以使用内存了。以*p = 7为例,假设p的逻辑地址经过编译后是300,首先根据逻辑地址(段号 + 段偏移)和段表中的基址算出线性地址(虚拟地址),然后内存管理单元(MMU)会根据虚拟地址和页表算出物理地址。由于这个地址转换过程如果用软件实现会比较慢,所以CPU设计了MMU这个硬件来自动完成转换功能。MMU算出物理地址(如7300)后,将其打到地址总线上,就把7存储到对应的物理内存单元中,实现了*p = 7的操作。
  2. 多进程地址分离与相互影响消除
    • 当有多个进程时,比如父子进程执行同样的代码,子进程执行*p = 8p还是300。在执行过程中,由于父子进程的段表基址不同(子进程的段表基址是根据其自身分配的虚拟内存计算的),所以算出的虚拟地址不同。
    • 又因为之前将共享的页设置为只读,当子进程要写入数据(如写入8)时,就会触发写时复制机制。此时会新申请一个内存页,修改页表,建立新的映射,将新的物理地址(如8300)与虚拟地址关联起来。这样,父进程和子进程就通过各自的映射表实现了地址的分离,避免了相互影响,每个进程都能独立地访问和使用自己的内存空间,就像我们之前讲过多进程在内存中相互影响的问题,通过段表和页表的配合,得到了完美解决。

相关文章:

  • 第十五篇:MySQL 高级实战项目:构建高可用、可观测、性能优化一体化数据库平台
  • 【SpringBoot实战】优雅关闭服务
  • ubuntu/windows系统下如何让.desktop/.exe文件 在开机的时候自动运行
  • 【深度学习】线性因子模型:数据降维与结构解析的数学透镜
  • TDenigne 集群可视化管理
  • 华为OD机试真题——文件目录大小(2025 A卷:100分)Java/python/JavaScript/C++/C语言/GO六种语言最佳实现
  • 设计模式——工厂方法模式(创建型)
  • RabbitMQ 高级特性
  • Unity 模拟高度尺系统开发详解——实现拖动、范围限制、碰撞吸附与本地坐标轴选择
  • C语言基础(08)【循环结构】
  • PCB设计教程【强化篇】——USB拓展坞原理图设计
  • 生成式AI模型学习笔记
  • Fastapi 学习使用
  • 告别压降损耗与反向电流困扰:汽车电子电源防反接方案全面解析与理想二极管应用
  • 【Unity笔记】Unity WASD+QE 控制角色移动与转向(含 Shift 加速)实现教程
  • 【Python进阶】CPython
  • 分析XSSstrike源码
  • 关联子串 - 华为OD统一考试(JavaScript题解)
  • 姜老师MBTI课程:4条轴线的总结
  • ssh连接断开,保持任务后台执行——tmux
  • 广东省建设安全管理协会网站/关键词排名是由什么决定的
  • 敦煌网站做外贸怎样/如何免费创建自己的网站平台
  • 鄂州市城乡建设委员会网站/企业管理咨询培训
  • 集团网站改版方案/百度下载安装2022最新版
  • wordpress rss源/保定seo推广公司
  • 做网站教程百度云/手机游戏性能优化软件