当前位置:嗨网首页>书籍在线阅读

04-内存区域

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

9.1.2 内存区域

内核将具有某些相同特征的页组织成块(blocks),例如读写权限。这些块叫作内存区域(memory regions),段(segments),或者映射(mappings)。下面是一些在每个进程都可以见到的内存区域:

  • 文本段(text segment)包含着一个进程的代码、字符串、常量和一些只读数据。在Linux中,文本段被标记为只读,并且直接从目标文件(可执行程序或是库文件)映射到内存中。
  • 堆栈段(stack)包括一个进程的执行栈,随着栈的深度变化会动态伸长或收缩。执行栈中包括了程序的局部变量(local variables)和函数的返回值。
  • 数据段(data segment),又叫堆(heap),包含一个进程的动态内存空间。这个段是可写的,而且它的大小是可以变化的。这部分空间往往是由malloc分配的(这将会在下一节讨论)。
  • BSS段[3](bss segment)包含了没有被初始化的全局变量。根据不同的C标准,这些变量包含特殊的值(通常来说,这些值都是0)。

Linux从两个方面优化这些变量。首先,因为附加段是用来存放没有被初始化的数据,所以链接器(ld)实际上并不会将特殊的值存储在对象文件中。这样,可以减少二进制文件的大小。其次,当这个段被加载到内存时,内核只需根据写时复制的原则,简单地将它们映射到一个全是0的页上,通过这种方式,可以高效地把这些变量设置成初始值。

大多数地址空间包含很多映射文件,比如可执行文件执行自己的代码、C和其他的共享库和数据文件。可以看看/proc/self/maps,或者pmap程序的输出,我们能看到一个进程里面有很多映像文件。

本章将介绍Linux提供的如何获取和返回内存,以及创建、销毁映射的各种接口。