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

Linux 进程地址空间

在学习进程时,提到虚拟内存空间这个概念,但由于涉及到的知识比较多,当时并没有细讲。要搞清楚虚拟地址空间需要大量时间,本文打算先浅浅地讲述一番,以后会在这个话题有更多更广的讲解。看完本文,进程部分的一些问题将得到解答,如:虚拟内存空间是什么?有什么用?

何为虚拟地址空间

在进程部分,我们知道进程是由PCB+数据构成的,PCB 是一个结构体,它的具体实现叫做task_struct。这个 task_struct 管理着一块空间,这块空间就是虚拟地址空间

既然叫 “ 虚拟 ”的空间,那它肯定不是指的我们那块真正的空间——内存 ,其实学过 C 语言就可以自己验证:创建一个死循环不断开辟空间,如果编译器拿到的是真是的内存,那么你的电脑就会因为内存爆满而崩溃,但事实是只是程序崩了,电脑屁事没有。

虚拟地址空间是模拟出的一块 “ 空间 ”,它的容量和内存一样大,每个进程都有自己的一个虚拟地址空间。这里可能有人要问了:你说虚拟地址空间的大小和内存一样,而且每个进程都有自己的一个虚拟地址空间,但是电脑里面会有很多进程啊,就算是模拟出来的空间,你存放的数据总是真的吧!你哪里来那么多的空间模拟呢?

这时候系统说话了:进程啊,我给你开了 4GB 的空间(假设电脑有 4GB 的内存),你要用空间的话你尽管用,只要没超过 4GB,你要用多少我都给你补。

系统这家伙看着挺大方,给你补还。但当内存满了,它没有多余内存了,怎么办?这时候某些进程就遭殃了。

系统会把一些不常用的进程暂时放到硬盘的 Swap 分区里,如果这里也满了,系统甚至会把一些进程直接杀死。

虚拟地址空间和内存的关系

通过上面的内容,相信你已经对虚拟地址空间有了一定的了解,接下来讲讲虚拟地址空间和内存的关系。前面也说,我们知道,电脑是把真实的内存空间中的地址隐藏起来的,无法查看。那么,虽然虚拟地址空间是模拟出来的,但是你的数据是真实的呀!你总要在内存中开辟空间存放它们,我们只有虚拟的地址,怎么在内存中找到它们呢?

想通过虚拟地址找到真实的内存空间,我们要用到一个叫 “页表” 的东西,这个在进程部分也讲过。页表存储着虚拟的地址,同时它又存储着真实的地址,一个虚拟地址对应真实地址,有点类似哈希表。

一个进程,一套页表

对于页表,有一个特殊的词 “缺页中断”。我们之前也看到,电脑中是有多个进程同时占有内存的,但是给每个进程一开始都分配完整的内存是不可能的,既是做不到也是不值得,做不到这个不用多说,那不值得呢?你想啊,一个进程分配 4GB 的空间它用的完吗?大部分情况是用不完的吧,所以这会导致资源的浪费。

系统的做法是:进程申请虚拟内存时,内核只会在页表里做标记,分配好虚拟地址,不会立刻分配物理地址和物理内存。当进程第一次读写这块虚拟内存时,CPU 就会去查页表,发现没有对应的物理地址,就会立刻触发缺页中断,找一块空闲物理内存填上,再更新页表。

写时拷贝再深入

有了以上知识,我们现在可以对进程部分的写时拷贝这个知识点进行更加深刻的理解了。

我们之前说过,父进程拷贝出的一份副本作为子进程。对于子进程的一切,在没有做出改变时,其实和父进程大差不差,页表也是直接拷贝过来的。子进程页表直接继承父进程页表中的虚拟地址,然后开辟新的内存空间供自己使用。这也是为什么在查看父子进程的数据地址时,我们会发现不同的数据拥有同一个地址。

那么,我们也能很好地解释接收 fork 返回值的变量为什么可以有不同的值了,其实就算改变量在父子进程中都有相同的虚拟地址,但是真实的内存地址是不同的。

写时拷贝和 “缺页中断” 都是是 “懒加载” 思想的应用,即:能不复制就不复制,能拖就拖,直到万不得已才做

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

相关文章:

  • HTML实现DOCX文档版题库图文考试系统(修订)
  • ikd-Tree:FAST-LIO2中的增量式地图管理结构
  • 求职用前程无忧还是智联招聘?选对平台少走弯路
  • prerender-loader完全指南:轻松实现Webpack预渲染提升首屏加载速度
  • nodejs后端服务如何接入taotoken实现异步调用多模型对话能力
  • S200驱动器报A1489故障
  • Oracle Redo日志与Undo回滚段损坏恢复实战
  • 企业直播核心功能深度指南:互动、录制与数据分析
  • 基于FPGA实现ADC366X系列芯片配置及数据采集
  • 终极指南:快速掌握Vue 3树形结构组件的完整使用技巧
  • Paper2Poster深度解析:多智能体架构如何重塑学术海报生成范式
  • 【电池】插电式混合动力汽车PHEVs性能的模拟【含Matlab源码 15452期】
  • 你的 FlashAttention 真的在跑吗?几个简单方法确认
  • Linux库制作与使用(二):ELF文件与链接过程
  • 2026年靠谱的温州卡包批量定做公司哪家好 - 品牌宣传支持者
  • Android动态换肤终极指南:5分钟掌握零入侵皮肤切换框架
  • 快速复习C语言
  • 【飞机】数据驱动的多传感器飞机健康监测系统【含Matlab源码 15551期】
  • 3大实战技巧:使用mootdx高效获取与处理通达信财务数据
  • 老木匠、临界质量与Log曲线——一个46岁架构师的AI生存哲学
  • 2026聚氨酯砂浆生产厂家哪家好?聚氨酯砂浆定制厂家技术全解析 - 栗子测评
  • ascend-transformer-boost (ATB) - Transformer推理加速实战
  • JDK6→JDK7→JDK8 重点技术更新(精简背诵版)
  • 【仅限首批200名开发者】Gemini多模态搜索性能诊断工具包(含Latency Heatmap生成器+跨模态Embedding可视化插件)
  • TranslucentTB:重构Windows任务栏视觉体验的技术架构深度解析
  • 陈,跳台记录仪 大鼠跳台记录仪 小鼠跳台记录仪
  • 安装docker和显卡支持
  • 【图像重建】交替方向乘子法ADMM深度图重建三维重建【含Matlab源码 15543期】
  • java学习笔记(3)
  • PHP 的 resource(如数据库连接、文件句柄)不能被序列化。