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

OS——内存管理+程序加载

内存的管理和使用

  • 内存是被分成一个个4KB大小的块来管理和使用的,每个块可以叫做一个页框(或者页帧)
  • 内存与磁盘进行读写交互都是按照页框为单位。即使此次要读或者写的数据不够4KB,也是按照4KB进行读写(可能会多读或多写,但由于局部性原理,这也无伤大雅)。加载完所有代码后发现最后一个页框的一部分没有被使用,它也不能被别人使用,浪费就浪费了(这就造成了内存内碎片)
  • 所有的页框(内存块),都被一个struct page结构体进行描述,所有的struct page结构体被一个数组组织起来统一管理,所以我们对内存块的操作就转换成了对这个数组的增删改查。(比如要申请一个空闲内存块,就遍历这个数组看看哪个struct page中的标记位是未被使用)
  • 比较巧妙的是,数组中的每一个struct page对应的下标就是这个struct page所管理的内存块在整个内存中的偏移量。利用这一点,我们可以发现:通过struct page,我们可以用其在数组中的下标*4KB来找到它所管理的内存块对应的起始地址;通过内存地址/4KB可以得到页框号(对应的内存块),再把页框号当作下标就可以直接找到该内存块对应的struct page管理结构。page知道自己管理那块,通过地址也可以找到管理者以及块首地址,整个过程都是O(1)的时间复杂度,非常高效

综上,内存分块使用,被数据结构管理,会导致内存内碎片问题。一个文件缓冲区实际上就是一个struct page链表,而释放一个内存就是修改struct page的标志位而已。


真正的页表

我们都知道,虚拟地址空间与实际内存空间的映射关系是记录在页表上的,但实际上这种映射不是逐字节映射的,而是逐内存框映射。

先来看一下如果逐字节映射会出现什么情况:

实际上,虚拟地址逻辑上也被分块,所以页表只是做页框到页框之间的映射:

页表的大小最大是4MB,但是大概率根本用不到后面的众多页表,也就不会开空间,所以实际上是远远小于4MB的。

初次之外,页表中还有很多的标志位

写时拷贝的原理就是把子进程的页表项的标志位都改成只读,这样子进程在修改的时候就会发生错误,然后陷入软中断,由OS重新申请内存并映射到子进程页表上。

缺页异常(懒加载)的原理也是如此,发现是否命中为否就会触发软中断,将数据加载到内存上。

越界不一定会报错,有可能判断的时候虚拟地址恰好是在合法的范围内,这时就把它当成了缺页中断,加载后访问了随机内容。


内存外碎片以及读内存效率问题的解决

虚拟地址空间可以让逻辑上连续的代码和数据映射到不同的地址处,这样一来就不会出现两个内存块中间的内存块由于太小分配不出去而导致的内存内碎片问题。

不过如果把一个变量拆分存放到两个页框,这样的话对于CPU读取来说需要读两次,还需要切分拼接等操作,效率会变低。因此在存放数据时进行内存对齐实际上避免了将一个变量存储在两个不同的页框中的情况,也就提高了CPU读内存的效率。内存对齐实际上是一种以空间换取时间的做法。


程序加载

  • 当我们点击运行一个程序的时候,OS创建一个进程PCB,当前OS知道这个程序的存放位置(通过环境变量或者命令行的当前工作目录),所以OS会把可执行文件的全部或者部分内容加载到内存中,并将内存地址与PCB的虚拟地址空间建立映射。
  • 接着OS把形成的页目录表的地址放到CR3寄存器中,以供MMU转换虚拟地址使用。
  • 由于可执行文件是ELF格式,CPU可以从文件特定位置取出main函数的地址放到PC寄存器,至此程序就可以跑起来了。OS也根据这种ELF格式给不同的代码或数据设置访问权限。

综上,程序的运行,和硬件,OS以及文件本身的格式都有关系

http://www.jsqmd.com/news/666604/

相关文章:

  • 2026年3月国内知名的电子汽车衡企业口碑分析,电子汽车衡/源头治超管理系统/装裁机自动累计秤,电子汽车衡直销厂家推荐 - 品牌推荐师
  • Function Calling 最佳实践:10个让代码质量提升10倍的工程技巧
  • 2026-04-18 模拟赛总结
  • 从SPI引脚别名到实战选型:当芯片手册上的SDI/SDO把你搞晕时,这份避坑指南请收好
  • 当芯片研发流程引入AI,我们需要这个checklist
  • 告别依赖地狱:用linuxdeployqt和dpkg为你的Qt应用打造一键安装的deb包(Ubuntu 20.04实测)
  • 基于FPGA与Matlab算法的超声多普勒频移解调系统:DDS生成信号、混合与滤波处理、FFT...
  • 微信在Linux上的默认数据目录
  • ILSpy终极指南:如何快速掌握.NET反编译神器
  • Manjaro新手避坑指南:从依赖缺失到签名错误,一次搞定所有安装报错
  • Tool之Jira:从零到一,构建高效敏捷团队的Jira实战配置与核心流程详解
  • 2026年宁波VBEAUTY科技美肤公司推荐榜/vbeauty美容店,vbeauty面部清洁,vbeauty面部补水,vbeauty面部肌底护理 - 品牌策略师
  • AGI物流决策引擎实测对比:传统TMS vs. 类脑调度系统,响应延迟下降83%,成本优化率达19.4%——数据来自顺丰、菜鸟闭门测试
  • CSS Grid布局如何实现项目水平垂直居中_掌握place-items属性的用法
  • 2019服务器IIS配置
  • Zotero-SciHub插件实战:学术文献自动获取的技术原理与实现深度解析
  • 英飞凌TC387 PMSM FOC电机控制Demo程序深度解析
  • FPGA数码管驱动避坑指南:从共阴共阳到分时复用,新手最容易搞错的5个点
  • 安全代码审查
  • OpCore Simplify:三步快速配置黑苹果的终极自动化工具指南
  • OpenClaw 已过时?在 VS Code 中运行 Hermes Agent!
  • 如果大模型懂电路,那也是工程师塞进去的
  • 2025终极指南:如何快速上手Il2CppDumper进行Unity逆向工程
  • 5分钟完美移植:在Windows和Linux上使用macOS风格鼠标指针的完整指南
  • Joplin跨设备同步冲突:数据一致性保障机制解析
  • 从CloudCompare的ccViewer源码入手,拆解一个工业级Qt+OpenGL点云查看器的架构设计
  • 深聊硅胶胶带厂家,哪家口碑好且价格合理 - 工业品网
  • 华硕游戏本终极优化指南:如何用G-Helper释放硬件全部潜能?
  • FPGA新手必看:MIG配置DDR3 SODIMM内存条接口的5个常见坑点及解决方案
  • G-Helper技术架构深度解析:如何通过轻量化设计重构华硕硬件控制生态