首页 > 系统服务 > 详细

虚拟地址空间--用户进程看到的自己所占用的内存

时间:2016-02-03 11:41:06      阅读:373      评论:0      收藏:0      [点我收藏+]

我们知道内核管理物理内存,其实除了管理本身内存外,还必须管理用户空间中进程的内存,我们称这个内存为进程地址空间,也就是系统中每个用户空间进程所看到的内存。

 

传统的C语言编译出来的进程地址空间包含哪些对象呢?可以参照ELF文件格式对应看:

-->可执行文件代码的内存映射,称为代码段。【ELF中的代码段】

-->可执行文件的已初始化的全局变量的内存映射,成为数据段。【ELF中的数据段】

-->未初始化的全局变量,也就是bss段的零页。由于未初始化的变量没有对应的值,所以不需要放在可执行对象中,但是C标准规定了所有未初始化全局变量要被赋予特殊的值,所以内核需要将变量从可执行代码载入到内存中,然后把零页映射到该片内存上。【ELF中的bss段】

  所以全局变量是否初始化影响该变量在可执行文件中的位置,初始化的全局变量在数据段,未初始化的全局变量在bss段且默认置0。

  另外,静态变量也就是static变量,和全局变量在内存中的处理相同,即初始化的static变量放在数据段,未初始化的static变量放在bss段,static变量和全局变量的不同在于语言层面上的作用域不同。

-->用于进程用户空间栈的零页内存映射(不同于内核进程栈)。堆栈段是进程运行时使用,所以在可执行文件中不需要实际分配。【动态分配】

-->每一个诸如c库或者动态链接库等共享库的代码段,数据段和bss段也会被载入进程的地址空间。当然静态库会编译到可执行文件中,而动态的共享库需要运行时载入。【动态分配】

-->任何内存映射文件,任何共享内存段,任何匿名的内存映射,比如malloc分配的内存。【动态分配】

 

每个用户进程看到的内存或多或少都是上面的几部分,但是这些内存是怎么和CPU交互,需要内核做什么呢?

 

当内核将CPU使用权交给这个进程时,指向代码段的寄存器会被内核写入这个进程的代码段地址。

 

地址的分类:

逻辑地址:包含在机器语言中用来指定一个操作数或者一条指令的地址。每一个逻辑地址由一个段和偏移量组成,偏移量指明了从段开始的地方到实际地址之间的距离。

  所以,逻辑地址一般是表示在可执行文件中机器语言所使用的地址,语境一般在可执行文件的机器指令中。内核一般不使用逻辑地址这个概念。

线性地址(或叫虚拟地址):是否用于描述内核中的地址。

物理地址:用于内存芯片级内存单元寻址。

 

CPU中有一个用于将逻辑地址直接映射为物理地址的控制线路,它叫MMU。内存控制单元(MMU)通过一种分段单元的硬件电路把一个逻辑地址转换成线性地址,接着,通过一个分页单元的硬件电路将线性地址转换为一个物理地址。就是说,一个hello可执行文件的机器指令,在使用比如一个定义的全局变量时,可以不通过内核,结合当前进程页表,通过MMU将全局变量的逻辑地址转换为实际的物理地址。

 

虚拟地址空间--用户进程看到的自己所占用的内存

原文:http://www.cnblogs.com/minihaohao/p/5175056.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!