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

内存管理 : 02 内存分区与分页

从我的视角看内存管理课程内容

在操作系统的知识体系中,内存管理占据着极为关键的地位。我在上节课开启了内存管理的学习之旅,深知它与CPU管理一同构成了操作系统的核心支柱,这两部分管理妥善后,一个基础的操作系统雏形便得以显现,再融入设备驱动和文件系统,一个完整可用的小型操作系统就能诞生。所以,今天我要继续深入探索内存管理的奥秘。

回顾上节课内容

本次学习,我首先对上次课的知识进行回顾,目的有二:其一,加深对已学内容的理解与认识;其二,通过回顾引出新问题,为后续学习做好铺垫。实际上,上次所学内容尚未形成完整体系,存在的缺口正是今天要学习的重点,补上这部分内容后,知识框架才能完整。

内存分区在整个知识脉络中起着承上启下的作用,它引出的问题将带领我走进今天的新主题——分页。在此之前,我们主要探讨了分段管理方式,而今天,分页的概念将登场,最终我会明白分段与分页相结合,才是操作系统内存管理的真正模样。

我回忆起,操作系统管理内存的核心思想是让内存高效利用起来。基于冯诺依曼存储程序的思想,计算机的工作流程是将程序载入内存,再由CPU取指执行,在这个过程中,内存得以被使用。一个程序通常会被分为多个段,比如代码段和数据段,这样划分是因为不同段具有不同特性,符合编程习惯和程序运行需求。

当程序分段完成后,需要将其放置在内存中。具体做法是寻找空闲内存区域,比如将代码段存放在地址3000开始的合适空间,数据段放在地址1000开始的空闲处。但程序在内存中的地址并非固定不变,以代码段中“jump 40”这条指令为例,它实际要跳转到的地址应该是3040,这就需要进行重定位操作。我们通过建立段表来记录各段在内存中的起始地址,利用硬件设备结合段表寄存器LDTR实现运行时重定位,从而确保程序正确执行。

在多进程环境下,每个进程都有独立的段表LDT,进程切换时,PCB和LDTR随之切换,使得不同进程在各自的地址空间内运行,互不干扰。这部分知识与之前学习的多进程映射表相关联,实际上映射表就是这里的LDT。我深知,要真正掌握这些知识,仅靠课堂听讲远远不够,还需亲自完成实验六,通过实践加深理解。

引出内存分区

回顾完上节课内容,我开始思考程序放入内存的具体流程,这可概括为三步:第一步,程序分段,这由编译环节负责;第二步,在内存中寻找空闲分区,这正是今天的学习重点;第三步,将程序载入内存,同时初始化LDT并与PCB关联,此过程涉及后续要学的文件系统、设备驱动等知识。这三个步骤看似简单,却涵盖了编译、算法数据结构、内存管理、进程管理等多方面知识,充分体现了操作系统的系统性。

内存分区的方法在这里插入图片描述

在这里插入图片描述
接下来,我学习了内存分区的两种方法。第一种是固定分区,它如同将面包平均分给孩子,把内存等分成若干个大小相同的分区。但这种方法存在明显缺陷,因为程序对内存的需求大小各异,固定分区无法满足多样化需求,所以实际应用中并不合适。

第二种是可变分区,它更加灵活,能根据程序请求的内存大小,在空闲分区中划分相应区域。在这里插入图片描述在这里插入图片描述

例如,内存中0 - 100k被操作系统占用,100k - 200k被segment1使用,250k - 500k为空闲区域,当有100k的内存请求时,就从250k处划分出100k,划分后空闲分区和已分配分区信息都要更新。在这里插入图片描述
而且,当进程结束释放内存时,空闲分区表也会相应变化。

当存在多个空闲分区都能满足请求时,就需要选择合适的分区算法。在这里插入图片描述
常见的算法有最佳适配、最差适配和首次适配。最佳适配会选择最接近请求大小的空闲分区,这样会导致空闲分区逐渐变小,产生大量内存碎片;最差适配则选择最大的空闲分区,能使剩余空闲分区大小相对均匀;首次适配不考虑分区大小差异,直接选择第一个满足条件的分区,其优点是查找速度快,时间复杂度为O(1),而最佳适配和最差适配的时间复杂度为O(n)。这些算法各有优劣,在实际操作系统中,需根据内存使用特点综合选择,通常不会单纯使用某一种。实际上,物理内存最终是通过分页来分配,而内存分区算法主要用于虚拟内存处理,这一点我先记下,待后续学习虚拟内存时再深入理解。

分页的引入在这里插入图片描述

内存分区方法存在效率问题,其中最突出的是内存碎片。由于不断的请求和释放操作,无论采用哪种适配算法,都会产生内存碎片。在这里插入图片描述
当有160k的内存请求时,虽然总空闲内存为200k,但因碎片分散,无法满足请求。为解决碎片问题,可能会想到内存紧缩,即将已使用内存区域合并,释放出连续的大空间,但这会耗费大量时间,在紧缩过程中,CPU无法执行用户进程,导致上层用户程序无法运行,出现类似死机的现象,随着内存容量增大,这种方法愈发不可行。
在这里插入图片描述

于是,分页的解决方案应运而生。它将内存和程序请求都划分为固定大小的页,物理内存初始化时就被分成一页页,以4k为一页为例,通过map映射表记录每一页的使用状态。程序请求内存时,根据需求计算所需页数并向上取整,然后在物理内存中寻找空闲页进行分配。分页的优势在于避免了内存碎片问题,即使存在未被完全使用的页,浪费的内存最多也只是一页(4k),相比内存分区产生的大量碎片,浪费大大减少,而且无需进行耗时的内存紧缩操作。从物理内存角度,分页能有效减少浪费;从用户角度,用户习惯程序分段编写,所以操作系统需要同时支持分段和分页,这也是后续学习的重点。

分页后的地址计算与重定位在这里插入图片描述

程序通过分页方式放入物理内存后,仍面临程序执行的问题。以“jump 40”指令为例,需要确定40这个地址分配到了哪一页,以及最终要发出的地址是多少。假设每页大小为40,40位于第零页,如果它对应的物理页框是第五个,那么最终地址就是540。

计算最终地址需要借助页表,就像分段时使用段表进行重定位一样。页表也有对应的寄存器CR3,每个进程都有独立页表,进程切换时CR3随之切换。在实际计算中,以地址2240(16进制)为例,由于每页大小为4k(2的12次方),将地址右移12位,可得到页号为2,页内偏移保留。通过页号在页表中查找对应的页框号,假设页框号为3,因为每页4k,所以物理地址就是3×4k + 页内偏移,即3240。这些计算操作由硬件的内存管理单元MMU自动完成,只要将地址和页表起始地址提供给MMU,它就能根据页表进行重定位,计算出正确的物理地址。

至此,我对内存管理的学习有了更深入的认识。一个程序从分段开始,经过内存分区、分页,最终通过页表实现地址重定位并正确执行,这些知识相互关联,共同构建起操作系统内存管理的基本轮廓。后续我还将学习分段与分页的结合,进一步完善对内存管理的理解。

http://www.xdnf.cn/news/643717.html

相关文章:

  • Python实例题:Python打造漏洞扫描器
  • 【AI论文】KRIS-基准测试:评估下一代智能图像编辑模型的基准
  • LangChain4j HelloWorld
  • 分词算法BPE详解和CLIP的应用
  • 测试计划与用例撰写指南
  • SAP Commerce(Hybris)开发实战(二):登陆生成token问题
  • 企业级智能体 —— 企业 AI 发展的下一个风口?
  • 【公式】批量添加MathType公式编号
  • [Linux]磁盘分区及swap交换空间
  • 第38节:PyTorch模型训练流程详解
  • Baklib知识中台构建实战
  • [DS]使用 Python 库中自带的数据集来实现上述 50 个数据分析和数据可视化程序的示例代码
  • 【LangChain全栈开发指南】从LLM应用到企业级AI助手构建
  • LLM多平台统一调用系统-LiteLLM概述
  • MYSQL备份恢复知识:第五章:备份原理
  • 渗透测试流程-下篇
  • 定时任务调度平台XXL-JOB
  • 基于Python实现JSON点云数据的3D可视化与过滤
  • 美团2025年校招笔试真题手撕教程(三)
  • Spring 源码阅读(循环依赖、Bean 生命周期、AOP、IOC) - 5.2.15.RELEASE
  • 电路笔记(通信):RS-485总线 物理层规范 接口及其组成部分 瑞萨电子RS-485总线笔记
  • vue3中computed计算属性和watch监听的异同点
  • Qt实战教程:设计并实现一个结构清晰、功能完整的桌面应用
  • 机械师安装ubantu双系统:一、制作系统盘
  • React从基础入门到高级实战:React 核心技术 - 组件通信与 Props 深入
  • Pandas数据规整
  • 香橙派3B学习笔记3:宝塔 Linux 面板的安装
  • 2025年- H46-Lc154 --543. 二叉树的直径(深度、递归、深搜)--Java版
  • 华为OD机试真题—— 矩阵匹配(2025B卷:200分)Java/python/JavaScript/C/C++/GO最佳实现
  • MySQL的查询进阶