广州.NET培训
达内广州.NET培训中心

18087159764

热门课程

达内.net编程班:进程内存模型

  • 时间:2017-10-23
  • 发布:广州.net培训
  • 来源:达内新闻

编程语言基础入门学习之进程内存模型——内容摘要:

可执行文件和进程的差异

进程内存模型

使用readelf -l查看段映射

使用gdb查看运行期内存模型[付费阅读]

可执行文件和进程的差异

一个普通的程序编译完了以后,程序还没有运行就提供了虚拟内存地址空间,这个虚拟地址就已经有了。回过头来想一想这个事情,就会发觉虚拟地址的好处。

程序需要载入到内存中才能执行,既然每个程序都有一套完整的虚拟地址,那么在编译的时候就可以确定下来地址作用,比如某块地址用于映射程序可执行文件空间,运行期的堆、栈在别的地方分配。那么也就意味着编译时候可以确定执行时候放在哪,因为虚拟地址是我私有的,所以在编译时候就可以预先安排好虚拟地址。那么这就有很多好处,比如说.text段可以提前安排好了,起始地址加上偏移量就是函数在运行期的内存地址,编译汇编指令的时候就可以把地址写到汇编指令里面,编译时候就可以做这件事,所有的代码合并到.text段里面,既然这个地址已经确定下来了,里面有个函数指令,起始地址加上偏移量就是就等于这个函数的指针地址,这个地址就变成类似常量值。那调用这个函数时候直接call这个常量值就可以了,编译时候就能确定这个事情,这就是虚拟地址带来的好处。你如果是物理地址的话就麻烦了,因为物理地址你根本不知道你最终运行时候会挂在哪个地方,所以没有办法在编译时候把地址就确定下来但是虚拟地址可以因为虚拟地址是完整的一套独有的。所以我们在编译时地址都可以确定下来。这样在编译期通过虚拟地址就可以确定很多东西。

进程内存模型

接下来搞清楚可执行文件究竟怎么样映射到内存里面去。

我们可以看到可执行文件内部有很多段,但是不是所有的段都会载入内存里面去,有些数据只是存下来在调试时候用,但是程序执行时候不需要这些数据,那我没必要把它放到内存里面去。

首先可执行文件内部有很多段,运行时候也有很多段,这两个地方的确有相似的地方,但也有不一样的地方。它可能把可执行文件某些东西映射到运行时候里面,比如说可执行文件中.text段映射到运行时某段中,当我们读取数据的时候,假如数据没有载入,引发缺页异常,然后就会把可执行文件.text段数据换入到内存里,这样的话我们就可以读到指令。也就是说可执行文件和进程之间是有映射关系的,这个映射关系并不是一一对应的。在可执行文件有些数据段在运行时是不需要的,还有些段需要合并。

进程内存模型也是把地址空间分为一个一个段,这些段在初始化状态下的时候,它会和可执行文件中某些段建立映射关系,当我们读这些信息时,如果没有载入物理内存,会引发缺页异常,然后从可执行文件里把这些数据交换到物理内存里面,接下来就可以读到。因为我们从这里面读取的数据基本上分为两种状态,一种是只读的,另外一种运行期写的,运行期写的不要求写回去,只读的比如像指令肯定不能换出的,因为没有必要换出,因为需要把它干掉重新换入就可以了。

使用readelf -l查看段映射

$ readelf -l test

上面是程序运行时进程初始化时分配好的段,这个才是程序执行时候需要创建的段,下面有个映射表是可执行文件和进程模型的映射关系。

上面所有的段除了内存地址结束地址大小以外还有运行期标记位,例如RW代表可读写。例如下面.data .bss段被映射到3段,3段LOAD的标记位是RW。.text段映射到2段,2段LOAD标记位是R E只读可执行。也就是说这两种存在一定的映射关系。操作系统载入器通过这个表来确定哪些东西怎么样去映射。读数据时候怎么去读。然后确定虚拟地址空间的起止地址在哪。这样就确定了映射关系当我们去读内存的时候如果这数据没有载入到物理内存,那么就引发缺页异常,把这些数据从可执行文件里面读出来。

免责声明:本文由广州.net培训小编转载自网络,旨在分享提供阅读,版权归原作者所有,如有侵权请联系我们进行删除。

广州.net培训机构

上一篇:广州达内:正确运用异步编程技术的技巧
下一篇:达内广州校区:如何打造专属笔记服务

达内.net编程班:进程内存模型

广州达内:正确运用异步编程技术的技巧

广州达内老师分享.Net的性能

【广州达内】.Net培训的发展前景好吗?

选择城市和中心
贵州省

广西省

海南省