Linux/Unix地址空间

Posted by Harid六月 - 9 - 2011 Leave comments

从实际运用的角度来定义,我们说进程是正在运行中的程序。这意味着操作系统为程序把可执行文件载入到内存中,为程序访问命令行和环境变量做好准备,将程序开启运行。分配给进程的内存有五个概念上不同的区域:

1、“代码”

这个区域经常被称为“文本段”,可执行指令存放在这个区域。如果可能的话,Linux和Unix会安排好相同程序的多个运行实例共享这些实例的代码,任何时刻内存里只有一份相同程序的指令拷贝(这对于运行中的程序来说是透明的)。可执行文件中包含文本段的部分是“文本节”。

2、“初始化为非零的数据”

初始化为非零值的静态分配数据和全局数据存放在数据段当中。运行相同程序的每个进程都有自己的数据段。可执行文件中包含数据段的部分是“数据节”。

3、“初始化为零的数据”

缺省初始化为零的全局数据和静态分配的数据存放在进程的BSS区域当中,BSS是一种通俗的叫法。每个运行相同程序的进程都有自己的BSS区域。当程序运行的时候,把BSS数据放到数据段。在可执行文件中,BSS数据存储在BSS节当中。

对于Linux/Unix可执行程序的格式来说,只有初始化为非零的变量才在可执行程序的磁盘文件中占用空间。因此,如果有个大数组声明为“ static char somebuf[2048];”,这个大数组自动用零来填充,那么它占用的空间还不到2KB(有些编译器提供了选项,可以让你将零初始化的数据放入数据段中)。

4、“堆”(Heap)

动态内存来自于堆(通过malloc()和一些友元函数得到)。当在堆上分配内存的时候,进程的地址空间会增大,正如你对运行中的程序用ps命令所看到的一样。

虽然将内存还给系统并缩小程序的地址空间都是可能的,但是几乎不这样做(我们把释放不再需要的动态内存与缩小地址空间区别开)。

通常情况下,堆会“向上增长”。·这意味着加到堆上的后面的条目的地址比前面条目的地址在数值上要大些。堆紧接着数据段的BSS区域开始也是很常见的。

5、“栈”(Stack)

20110609075

堆栈段是分配本地变量的地方。本地变量是声明在函数体开始的左大括号内的变量(或其它左大括号),不可以定义成static变量 。

在大部分体系结构上,函数参数也放在栈里,还有编译器产生的“不可见”的簿记信息也放在栈里,例如,这些簿记信息中有存放函数返回值和返回地址的存储空间,返回地址表示从函数返回到函数调用者的地址(有一些体系结构用寄存器琮完成所有这些工作)。

正是在函数参数和返回值上使用了栈才使“递归”函数的编写变得方便了(函数调用自己)。

当函数有返回的时候,存储在栈里的函数变量“消失了”,栈里的空间又可以重用了于后面的函数调用。

在大部分现代的体系结构上,栈是“向下增长”的,这意味着调用链上的条目越深,其地址在数值上越小。

 

当程序在运行的时候,初始化数据、BSS和堆区域通常放入一个单独的连续区域:数据段。堆栈段和代码段与数据段分隔开,并彼此分开。

——摘自《实战Linux编程精髓》

   声明:本文采用 BY-NC-SA 协议进行授权 | 星期九
   原创文章转载请注明:转自《Linux/Unix地址空间

  1. 过一段时间我也要开始接触linux了,这年头想找个windows平台的C++开发工作,你别说,嘿,还真不简单!

    • @C瓜哥, MFC应该还好吧?用的企业还是很多的,不过像你的话,我觉得熟悉Linux是很有必要的。

        • @C瓜哥, 熟悉系统编程。其实你弄C++的话,我觉得主要是C++的一些东西 ,像STL、然后数据结构、算法。能够熟悉Linux下的一种GUI最好。我不是专业的,你可以问你们老师嘛,在学校里,老师是很好的资源啊。

      • @Harid,
        1、大一的时候装过几次linux,后来都是暴力删除分区告终,唯一印象就是放视频CPU占用100%,也许是联想机器的问题(没驱动,特效也打不开),这次我还是用虚拟机吧
        2、老实说,学linux,就可以有备无患嘛 😀
        多个就业面

        • @C瓜哥,
          1、本来暑假打算去实习的。结果来的公司少,而且还一个比一个失望。暑假主要是以复习基础、做题为主了
          2、我们学校排课相当不合理,下学期居然有Linux和计算机图形学,晕。学完了,校招都过了
          3、老实说,我们学校的老师资源也不咋的。好的老师尽往外校跑了(大一就有一个,课都没上完,就去川大工作了)


分享按钮