任何程序最终都只会产生指令和数据。

进程的内存分布

在上图环境中,当程序加载到内存中运行时,Linux系统会给当前进程分配一个2^32大小的空间。
该空间主要分为两块:

  1. 用户空间(user space)
  2. 内核空间(kernal space)

两块空间共占用4G大小的空间,虚拟地址为0x00000000至0xFFFFFFFF,分隔点为0xC0000000。
程序运行时,程序的用户空间是(程序)私有的,内核空间是公共的

用户空间

程序运行时的用户空间从低地址到高地址主要分为如下几块:

  1. 系统保留区/不可读区
  2. 代码段(.text)和只读数据段(.rodata)
  3. 数据段(.data)
  4. 数据段(.bss)
  5. 堆区(.heap)
  6. 加载共享库(*.dll/*.so)
  7. 栈区(stack)
  8. 命令行参数和环境变量

系统保留区存放着操作系统的预留的内容,不可访问,如空指针nullptr。

代码段存放着程序的指令,只读数据段存放着一些字符串常量。

数据段(.data)存放着程序已经初始化且初始值不为0的全局变量和静态变量。

数据段(.bss)存放着程序未初始化或者初始化为0的全局变量和静态变量。

堆区用于程序运行时的动态内存申请,空间较大,从低地址向高地址方向增长。该空间在程序运行时系统不会自动管理,申请的内存用完需要手动释放。

加载共享库主要用于存放系统运行时需要加载进来的共享库。

栈区用于程序中的函数运行,空间相对栈区较小,且从高地址向低地址增长。该空间在程序运行时由系统自动管理,申请的内存不需要手动释放。较大的函数或者无休止的递归函数容易导致栈溢出。

内核空间

程序运行时的内核空间从低地址到高地址主要分为如下几块:

  1. ZONE_DMA
  2. ZONE_NORMAL
  3. ZONE_HIGHMEM

参考资料

施磊老师C++基础课程;
《深入了解计算机原理》第7章

最后修改日期: 2023年7月27日

留言

撰写回覆或留言

发布留言必须填写的电子邮件地址不会公开。

3 + 5 =