【Linux】进程虚拟地址空间
进程虚拟地址空间打破了我一直以来对于程序地址空间的认识,它真的好神奇。
我们首先来看一下下面这段代码:
1 #include<stdio.h>2 #include<unistd.h>3 /*4 *定义一个全局变量5 *创建子进程6 *修改变量值,再取地址,观察地址是否一样7 * */8 int glo_val=10;9 int main()10 {11 pid_t ret = fork();12 if(ret < 0)13 return 0;14 else if(ret == 0)15 {16 //child17 glo_val = 20;18 printf("I am child,glo_val = %d,address = %p\n",glo_val,&glo_val);19 }else if(ret > 0)20 {21 //father 22 printf("I am father,glo_val = %d,address = %p\n",glo_val,&glo_val);23 }24 return 0;25 }
我们来看一下它的运行结果:
是不是很神奇!!!
打印出来的两个地址相同,但是!值不一样!!
就非常奇怪啊,为什么会这个样子呢?难道我拿的地址是假地址?我取地址的方式有误?但是我检查过了,没有毛病,所以这个可能是某个我不知道的知识引起的,于是,我去查了查,下面就给大家解密。
通过上面的程序和它的运行结果,我们可以发现:变量内容不一样,所以父子进程输出的变量绝对不是同一个变量,但是地址值是一样的,说明这个地址肯定不是物理地址!!!打印的这种地址叫做虚拟地址。
操作系统为什么要弄一个虚拟地址出来呢?
提高内存的使用率
虚拟地址:我们用户是看不到物理地址的,那大家可能就有疑问了,我取地址取的不是地址吗?是地址,只不过是虚拟地址,真正的物理地址是由OS统一管理的。OS需要将程序中的虚拟地址转化为物理地址。
进程虚拟地址空间
在32为操作系统下,OS为每一个进程无差别的虚拟出4G的虚拟地址空间,程序在访问内存的时候,访问的是虚拟地址空间,既然是虚拟地址空间,那就不能直接存储数据,存储数据还是得存储在真正的物理空间里,于是OS就需要将虚拟地址空间转化为物理地址进行访问。那怎么转化呢?就使用我们接下来将要提到的页表。
为什么OS要给每一个进程都虚拟出来一个进程虚拟地址空间呢?为什么不直接允许进程访问物理内存呢?
因为各个进程访问同一个内存地址空间,就会不可控,可能会导致越界访问。在有限的内存空间里,进程它是不知道哪块内存是被其他进程使用的,也不知道哪块内存是空闲的。所以,在这种场景下,让进程直接访问物理内存,一定会导致多个进程在访问物理内存时出现混乱。所以,内存由OS统一管理起来,但是又不能采用预先分配内存的方式给进程,因为OS也不清楚进程真正要保存多少数据,不知道分配多少内存给进程合适,于是操作系统就虚拟的给每一个进程分配了4G(32位操作系统下)的地址,这个地址是虚拟的地址。
进程需要保存数据,或者申请内存的时候,操作的都是虚拟地址,让操作系统再给进程进行分配,同时也节省空间,用多少分配多少,这样是不是就很合理。
每一个进程无差别的使用拿到的虚拟地址,OS会将虚拟地址通过页表映射转换为真正的物理地址。
页表映射
进程虚拟地址空间和物理内存之间存在着映射关系,就是页表映射,将虚拟地址分成一页一页的,将物理内存分为一块一块的,通过页表来记录虚拟地址和物理地址的映射关系,页表由页号和页内偏移构成。
我们可以通过虚拟地址+页表的方式来找到物理地址。
- 虚拟地址 = 页号+页内偏移
- 页号 = 虚拟地址 / 页的大小
- 页内偏移 = 虚拟地址 % 页的大小
这样我们就能根据页的起始地址找到具体的物理地址。
同时需要注意的是,在进行内存分配的时候,我们不采取连续分配的方式,而是采用一页一页离散分配的方式,主要是为了防止产生内存碎片。
最后总结一下:
- 每个进程都有独立的虚拟地址空间,进程访问的并不是真正的物理地址。
- 虚拟地址可以通过每个进程上面的页表与物理地址进程映射,获得真正的物理地址。。
- 页表在每个进程的内核虚拟地址空间里
- 如果虚拟地址对应的物理地址不在内存当中,就会产生缺页中断,真正分配物理地址,同时更新进程的页表,如果此时物理内存已经耗尽,则根据内存替换算法淘汰部分页面至物理磁盘中。
【Linux】进程虚拟地址空间相关推荐
- Linux进程虚拟地址空间
1. 前言 谈到Linux进程虚拟地址空间,还要从程序说起.本文通过分析程序的编译执行过程,分享了Linux进程虚拟地址空间的结构.组织和创建,并通过分析Linux内核源代码,总结了进程.进程虚拟地址 ...
- Linux虚拟内存和进程虚拟地址空间简述
后台开发经常会问此类问题,虽说难度不大,但是知道和不知道还是有区别的.以下的内容总结自<深入理解Linux内核>第一章,仅仅是简述,没有深入研究,毕竟内存管理这一块内容超级多,感兴趣的同学 ...
- Linux内核虚拟地址空间,-3G的由来。各个进程的虚拟内存4G,内核总在3-4G。内核的虚拟空间地址-3G,总是指向物理内存的0-1G地址,各个进程的虚拟内核共享这个物理内存
Linux内核地址空间划分 通常 32 位 Linux 内核地址空间划分 0~3G 为用户空间,3~4G 为内核空间.64 位内核地址空间划分是不同的. Linux内核高端内存 当内核模块代码或线程访 ...
- 14 [虚拟化] 虚存抽象;Linux进程的地址空间
14 [虚拟化] 虚存抽象:Linux进程的地址空间 南京大学操作系统课蒋炎岩老师网络课程笔记. 视频:https://www.bilibili.com/video/BV1N741177F5?p=14 ...
- 2.4父子进程虚拟地址空间情况
内核区中,父进程和子进程的pid是不同的. 定义的局部变量pid在栈空间中,父子进程中栈空间中的pid不同,在父进程中为子进程的进程号,在子进程中为0 实际上,更准确来说,linux的fork()是通 ...
- 一篇长文叙述Linux内核虚拟地址空间的基本概括
x86-32位虚拟地址空间 就我们所知,Linux内核一般将处理器的虚拟地址空间划分为两个部分.底部比较大的部分用于用户进程,顶部则专用于内核.虽然(在两个用户进程之间的)上下文切换期间会改变下半部分 ...
- 【读书笔记】【程序员的自我修养 -- 链接、装载与库(二)】进程虚拟地址空间、装载与动态链接、GOT、全局符号表、共享库的组织、DLL、C++与动态链接
文章目录 前言 介绍 可执行文件的装载与进程 进程虚拟地址空间 装载方式 操作系统对可执行文件的装载 进程虚存空间分布 ELF文件的链接视图和执行视图 堆和栈 Linux 内核装载ELF & ...
- 父子进程虚拟地址空间情况
父子进程虚拟地址空间情况 笔记来源于牛客网<Linux多进程开发> The child process and the parent process run in separate mem ...
- 【Linux】虚拟地址空间
文章目录 1. 物理地址和虚拟地址定义 2. 虚拟地址空间分布 2.1 内核空间 2.2 栈(stack) 2.3 堆(heap) 2.4 BSS段 2.5 数据段(Data) 2.6 代码段(tex ...
最新文章
- 为什么不记录慢速查询?
- 读了这篇文字,做年薪百万的NLP工程师
- 釜底抽薪:掌控能源成本,根治企业能源损耗
- 分布式系统中的限流与熔断
- 【Python Flask】使用Ajax从后台请求数据
- idea mac 替换_Mac软件IntelliJ IDEA 上的快捷键,让你的工作更加顺畅
- html5media 网页播放视频,html5media 在IE8播放视频黑屏
- 使用负边距创建自适应宽度的流体布局
- lsqcurvefit拟合结果为复数_使用科学计算器计算复数与相量(提高篇)
- python web框架 多线程_Django基础一之web框架的本质
- MySQL学习笔记(一)基本查询操作
- 原生滑动选择器 html,自已开发完美的触摸屏网页版仿app弹窗型滚动列表选择器/日期选择器 - j.king...
- 三绕组变压器参数计算matlab,三绕组变压器等值参数计算
- 华硕x450jn拆机_华硕X450C系列笔记本怎么拆机清灰?
- ping内网一台虚拟机延时很大(hyper-v虚拟机)的解决办法
- 如何用C语言求两个数的较大值
- 鲁大师linux系统打印机驱动怎么安装,鲁大师怎么安装打印机驱动?鲁大师安装打印机驱动教程...
- 微信小程序使用setData方法修改data中对象或数组的属性值
- 学计算机的学后感,关于大学生计算机学习心得体会(精选4篇)
- Spring Boot集成海康威视NVR
热门文章
- python飞书到期提醒
- 环形网络潮流计算matlab 利用matlab编程计算任意环形网络牛拉法潮流计算程序
- c语言实验报告绘制钟表,单片机时钟程序实验报告
- 近期接触和学习的新技术
- html中怎么让竖排表格变成横排,wps中横排表格怎么旋转90度变成竖排?(图)
- Python量化交易05——基于多因子选择和选股策略(随机森林,LGBM)
- 全黑的环境也能人脸识别?红外人脸识别技术助力人脸识别更自由
- 京东云开发者|京东云RDS数据迁移常见场景攻略
- 3ds Max 2019: Advanced Lighting 3ds Max 2019:高级照明 Lynda课程中文字幕
- 分贝测试发型软件,测量工具-分贝噪音测试尺子角度AR测距 trên App Store