论坛
潜水/灌水快乐,沉淀知识,认识更多同行。
ToB圈子
加入IT圈,遇到更多同好之人。
朋友圈
看朋友圈动态,了解ToB世界。
ToB门户
了解全球最新的ToB事件
博客
Blog
排行榜
Ranklist
文库
业界最专业的IT文库,上传资料也可以赚钱
下载
分享
Share
导读
Guide
相册
Album
记录
Doing
搜索
本版
文章
帖子
ToB圈子
用户
免费入驻
产品入驻
解决方案入驻
公司入驻
案例入驻
登录
·
注册
只需一步,快速开始
账号登录
立即注册
找回密码
用户名
Email
自动登录
找回密码
密码
登录
立即注册
首页
找靠谱产品
找解决方案
找靠谱公司
找案例
找对的人
专家智库
悬赏任务
圈子
SAAS
ToB企服应用市场:ToB评测及商务社交产业平台
»
论坛
›
运维.售后
›
运维.售后
›
Linux:进程地址空间
Linux:进程地址空间
石小疯
金牌会员
|
2024-10-2 06:41:20
|
显示全部楼层
|
阅读模式
楼主
主题
669
|
帖子
669
|
积分
2007
一、C语言内存管理基础
引入:从前我们知道一个指针指向的如果是一个常量字符串,那么这个就是指向的常量区,只读不可被修改,因此下面的程序会瓦解。
1、在我们C语言内存管理机制内里线性地址是有区域划分的。
我们怎样验证这个区域的划分是否正确呢?可以通过代码的方式在差异的区域创建变量然厥后取地址获取再进行比较
2、栈区和堆区是相对而行的!!
验证栈区:地址在变低
验证堆区:地址在变高
3、静态变量会被定义在全局区 只不过只会在作用域里使用。
二、fork遗留问题
历史遗留问题:为什么一个变量可以同时即是0又同时>0 ??
实行:
我们会发现同一个地址竟然读到了差异的内容!! 如果变量的地址是一个物理地址,是绝对不可能出现这种环境的,因此我们的变量地址必然是不是物理地址!!
——>结论:
我们平时C/C++内里使用的地址全都不是物理地址,而是虚拟地址! 用户是看不到物理地址的,而OS必须要负责将我们所看到的虚拟地址转化成物理地址!
三、进程地址空间
实在我们的之前所学的线性地址,并不是真正的物理内存,而是在PCB内部有一个指针指向了一块进程地址空间,然后虚拟地址会通过页表来映射到详细的物理地址。 ——>所以当我们创建出一个子进程后,他会拷贝一份和父进程一样的地址空间,然后当子进程想要修改对应的数据时,此时就会发生写时拷贝(由操纵系统自动完成),也就是重新开辟空间,在这个过程当中只有页表对应的物理地址发生了变革,左边的地址空间不会有任何的感知。
3.1 什么叫做地址空间
在32位的呆板中,有32位的地址和数据总线,所以每一根地址总线有0或1,实在从本质上来说盘算机能够识别是高低电频而并非二进制,所以1代表的是高电频,0代表的是低电频。——>
这个过程就是CPU通过像内存充电的形式告诉内存我需要哪个地址,然后内存就能够通过识别高低电频,形成一个物理数据,将地址对应的数据以同样的方式交给CPU。
所以
地址空间就是地址总线分列组合形成的地址的范围【0,2^32】
3.2 怎样理解地址空间的区域划分?
举个例子:比方说当前的桌子有100cm长,坐着小胖和小美,但是小胖经常骚扰小美,所以就在桌子中心画了一个三八线。 一人只有50cm的空间。所以从结构上就可以如下划分:
区域划分就是通过结构体内部的start和end去做划分
怎样理解区域的变大大概变小呢??——>
修改对应结构体内部的start和end即可
我们不但要看到地址空间的范围,我们要知道在范围内连续的空间中,每一个最小单元都可以有地址,这个地址可以被直接使用!!
3.3 什么是进程地址空间
所谓进程地址空间,本质上就是一个形貌进程可视化范围的地址空间内存在各种区域划分,对线性地址进行start、end即可 。本质上实在就是一个内核数据结构,和PCB一样,地址空间也是需要被操纵系统管理的:先形貌再组织。 而每一个进程都有本身的进程地址空间,PCB内部有一个指针指向这块空间!
四、页表
共识:当代操纵系统中,险些不做浪费空间和时间的事情!
4.1 写时拷贝、缺页中断、惰性加载
页表详细有哪些内容呢??——>
虚拟地址、物理地址、读写权限、标记位(对应的代码和数据是否被加载到内存中)
读写权限
就可以帮助我们做检查,比方说当前是常量字符区但是你却想修改,就会被操纵系统拦截,该非法请求就不会被发送到物理内存。
标记位
就是帮助们判断进程的代码和数据是否被加载到内存中,因为我们知道我们的进程对应的代码和数据是有可能处于挂起状态的(还没加载到内存)。
惰性加载:实在就是需要多少就加载多少。操纵系统对大文件是可以实现分批加载,也就是说当前的进程可能只有PCB在内存中,但是代码和数据可能还没立刻加载进来。
缺页中断:在执行进程的时候如果发现标记位表现当前代码和数据没有加载起来,就会发生缺页中断,也就是临时中断这个进程,然后等代码和数据加载进来之后,再规复原来的状态继续运行。
问题:一次加载进去不是更快吗,为什么需要检测了之后才通过缺页中断加载进去??
——> 一方面是因为可能这个文件特别大,所以没办法一次加载进去,就算是可以一次加载进去,但是你用不也是一点点去用么?? 所以
缺页中断办理的是初步局部性加载的问题,能够更公道的去使用内存!
!
写时拷贝:数据区的数据是按道理是可写的,但是一开始权限会被设置成只读(意思就是当前父子进程共享),一旦父子进程任意一方实验做修改的时候,发现当前的数据是只读的(但是这里不做异常处理,而是转而发生写时拷贝),然后开辟一块新的物理内存,修改页表的映射
4.2 进程地址空间是怎样切换的
进程PCB结构体里有对应的进程地址空间指针,所以进程切换就以为这进程空间地址空间被切换,而页表会被存储在CPU的cr3寄存器中,这实在属于进程的上下文信息,在进程切换的时候会被进程带走,背面再规复过来!!
4.3 进程创建的详细过程分析
进程被创建的时候,优先加载的是PCB结构体以及内里临应的进程地址空间结构体,然后他的代码和数据可能不会立刻被加载进来。
4.4 再次理解进程具有独立性
1、在内核数据结构上是独立的
2、物理内存中加载的代码和数据,只需要再页表上去表现。虚拟地址可以一样,但是通过页表映射差异的物理地址,就可以让父子进程解耦,一旦发生了任何异常,你释放你的我释放我的。
3、通过页表的虚拟地址映射物理地址,可以随便取地址,乃至是乱序。但是虚拟地址可以将一个线性的地址呈现给进程。
五、为什么要有进程地址空间?(重点)
所以我们可以对进程进行一个再总结:
讲个故事1:
一个豪富翁(操纵系统)有10亿美金,而他有四个私生子,但是四个私生子(进程)都并不知道对方的存在,所以他们都认为豪富翁只有他唯一一个儿子,而豪富翁告诉他们一旦本身去世了,就把所有的产业留给他,所以每个儿子也都信了,所以豪富翁实在给每个私生子都画了一个大饼(进程地址空间)。每个人都认为本身有十亿产业。 但现实上是这些私生子要多少才会给多少(进程需要多少空间操纵系统就给多少空间)
结论1:让进程以统一的视角看待内存
如许我进程就不需要关心说详细应该放在物理内存的什么位置,也不需要关心当前这个物理内存是否会影响别人的数据,这些工作都由操纵系统去完成。
故事2:
你过年的时候经常有压岁钱,但是你还小所以你经常会买到一些没有用的东西,于是你的妈妈就让你把钱交给他保管,等你需要买什么的时候,他再把钱给你,比如说当你想要买个一块钱的橡皮时,你妈妈就给了你一块钱,但如果你想花100块钱买个游戏机的时候,你的妈妈就不给你买,所以这个过程实在妈妈的作用就是会阻止你做一些不太适合的事情。
结论2:
增长虚拟地址空间,可以让我们访问的时候增长一个转换的过程,在这个转化的过程中我们可以对我们的寻址进行审查,所以一旦异常访问,直接拦截,该请求就不会到达物理内存,从而保护物理内存
结论3:
因为有地址空间和页表的存在,将进程管理模块和内存模块进行解耦合 !
申请物理内存的哪一块?优先加载可执行程序的哪一部门??又大概页表填写到什么地方??这是有Linux的内存模块去管理的,进程并不需要关心。
结论4:
实在变量名在定义的时候就已经被转化成一个个虚拟地址了,而我们之所以有a和&a,本质上是为了区分想获取的是变量的值照旧地址。
结论5:
从前我们所学习的C内存管理,实在本质上是进程地址空间,而内存管理是由Linux替我们完成的,我们上层语言并不需要关心详细的细节,只需要正常去通过对应的线性地址去使用就行了。
六、下令行参数和环境变量在栈的上面
所以环境变量和下令行参数是在栈之上的一个独立空间。 所以为什么子进程可以继承父进程的环境变量,
因为子进程启动时,父进程已经把对应的环境变量信息加载进去了, 他也是地址空间的一部门,所以他必然有页表去帮助我们建立虚拟地址和物理地址的映射,而当子进程创建的时候,子进程也会将父进程虚拟地址空间当中的环境变量的相关参数也给我们建立了一份映射,所以纵然你传参数,子进程也还是能够获得父进程的环境变量信息。
我们目前所关注的是用户空间。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
本帖子中包含更多资源
您需要
登录
才可以下载或查看,没有账号?
立即注册
x
回复
使用道具
举报
0 个回复
倒序浏览
返回列表
快速回复
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
or
立即注册
本版积分规则
发表回复
回帖并转播
回帖后跳转到最后一页
发新帖
回复
石小疯
金牌会员
这个人很懒什么都没写!
楼主热帖
解决OpenCV的imread/imwrite在Qt环境不 ...
解决图片无法设置hover,以设置图片的 ...
Linux的目录结构
qrtz表初始化脚本_mysql
C# GDI+ 画心形 跳动动画
Springfox与SpringDoc——swagger如何 ...
5个高并发场景优化的衡量指标 ...
Hive安装与启动
JDBC的对象说明
在 NGINX 中根据用户真实 IP 进行限制 ...
标签云
挺好的
服务器
快速回复
返回顶部
返回列表