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

linux----进程地址空间


前言


提示:以下是本篇文章正文内容,下面案例可供参考

一、空间分布

二、栈和堆的特点

(1)栈堆相对而生,堆是向上增长的,栈是向下增长的。

验证:堆是向上增长的

这里我们看到申请的堆,依次进行申请,堆的地址是向上增长的。

栈:向下增长(32位机器和64位机器)

验证:

这里为什么说要32位机器。对64位机器来说,栈是向下增长的,这个说法也许是不正确的。

至于为什么,这个为什么?64位对内存的分布进行了改进。下面打印的结果和32位地址结果相反


三.物理内存和虚拟内存

上面我们提到内存的空间分布是真实的物理内存吗?

我们创建子进程,父子进程代码共享,当一方发生写入时,就会发生写实拷贝,父子进程数据独立。

 这里我们发现,父子进程打印的值是不同的,这里我们可以理解,但是地址为什么是一样的,一个内存地址一样,值不一样,说明这个不是真正的物理内存,这个是虚拟地址。

1.地址空间和区域划分

我们知道地址空间的大小是4GB,操作系统将这个4GB根据每个进程的需要进行分配,每个进程都对所分配的空间独立使用权,比如栈,堆中的一部分。地址空间就是大蛋糕,区域划分就是分蛋糕,分配的对象就是进程。

操作系统要对进程地址空间进行管理,在linux中地址空间就是一个内核数据结构:struc mm_struct{}。进程的task_struct里有个指针,指向这个struct mm_struct{}.

这个里面描述了,可以使用的地址空间的范围。起始地址和结束地址之间的都是可以被使用的区域。

虚拟地址如何转换为物理内存?通过页表进行映射,这个过程是操作系统帮我们做的。

2.为什么要有虚拟地址空间

1.可以让申请的物理内存分布,通过虚拟地址让无序变为有序。

2.可以有效的进行安全检查,页表中其实还有权限字段,规定了数据是否可读可写。字符常量区权限就是只读,如果发生修改的转化,编译器识别到就会显示错误。

 3.将进程管理和内存管理进行解耦。

内存管理是操作系统帮我们做的,申请内存(分配),填充数据或者加载程序(是否有内容)。一个进程如果要对物理内存进行访问,首先要通过虚拟地址,在cpu中寄存器CR3中存储者页表的物理地址,硬件MMU进行虚拟到物理转化的过程中,先要通过页表字段查看内存是否分配和内存是否有内容,没内容或者被分配,这个进程就会被停止访问内存,将操作权限转交给操作系统,这时操作系统就会进行内存的分配和填充数据或者程序,将虚拟内存映射到分配的物理内存,这个过程也叫缺页中断,分配填充完,进程就可以继续访问。进程不参与内存管理,操作系统管理内存分配。

总结:一个进程有自己的页表,自己的空间地址,有自己的task_struct.进程的独立性通过页表的虚拟地址映射物理地址来体现。进程的切换也是不影响其他进程,因为进程的上下文数据在切换时就会被进程带走包括寄存器的内容,等到进程重新被调度,恢复上下文数据包括寄存器中的进程原来的内容。

3.如何理解父子进程变量地址相同而值不同

fok()创建子进程,子进程要以父进程为模板拷贝页表,地址空间。如果一方发生写入的时候,操作系统就会修改页表重新将物理内存映射到虚拟地址上,这也为什么上面的同一个变量打印的虚拟地址是相同的,值是不一样的。真实的物理地址我们是看不到,c++/或者c,我们可以看到的都是虚拟地址。

 


http://www.mrgr.cn/news/31696.html

相关文章:

  • 2024华为杯C题详细完整思路和视频讲解
  • 数据飞轮崛起:数据中台真的过时了吗?
  • 树莓派配置Qt+OpenCV
  • 数据结构|二叉搜索树
  • 【模板进阶】完美转发
  • 【CPU】CPU的物理核、逻辑核、超线程判断及L1、L2、L3缓存、CacheLine和CPU的TBL说明
  • Rust 运算符快速了解
  • 2024华为杯数学建模研赛F题建模代码思路文章研究生数学建模
  • thinkphp8 从入门到放弃(后面会完善用到哪里写到哪)
  • 【图文详解】什么是微服务?什么是SpringCloud?
  • Web_php_include 攻防世界
  • 6. Python 输出长方形,直角三角形,等腰三角形
  • 【编底层原理】打开百度,输入搜索关键字,点击搜索,会发生什么,底层是如何实现的
  • PLSQL 显示行号(隔条)
  • 2024年华为杯中国研究生数学建模竞赛C题(数据驱动下磁性元件的磁芯损耗建模)思路
  • Android命令行启动settings
  • 前端框架的对比和选择
  • 快手店铺多开甜羊浏览器
  • 网络安全详解
  • 迭代器和生成器的学习笔记