linux进程程序分段
-
linux系统针对每个进程都存在一个内存地址划分
-
一个进程通常由加载一个
elf
文件启动,而elf
文件由多个segments
组成。同样的,进程地址空间也由许多不同属性的segments
组成 -
linux的
segmen
t是虚拟地址空间中用于保存数据区域,只在虚拟地址上连续 -
segment
text
段(代码段) 包含了当前运行进程的二进制代码data
段(数据段) 存储已经初始化的全局变量bss
段 存储未初始化的全局变量- 这三个段是紧紧挨在一起的,因为三者大小确定 不会动态变化
heap
段(堆) 储存动态分配的内存中的数据stack
段(栈) 保存局部变量和实现函数/过程调用的上下文- 大小都是会在运行过程中变化,因此二者中间留有空隙 谁多谁就多占用间隙部位
mmap()
特殊段mmap
段的大小也是不确定的hea
p段,stack
段,mmap
段在动态增长的过程还是有重叠(碰撞)的可能,64位系统则不存在
-
加载顺序
- 首先
execve()
执行elf
,可执行文件的text
段,data
段,stack
段就建立了 - 在进程运行过程中,可能需要借助ld.so加载动态链接库,比如最常用的
libc
,则libc.so
的text
段,data
段也建立了 - 而后可能通过
mmap()
的匿名映射来实现与其他进程的共享内存,还有可能通过brk()
来扩大heap
段的大小
- 首先
C语言程序内存五大分区
- C语言程序经过编译变成可执行
elf
程序,某种程度上是二者是可以对应的 - 分区
- 栈区 存放函数的参数值,局部变量的值等。
- 堆区 由程序员手动开辟和释放的内存(
malloc
/new
) - 全局区(静态区)(
static
) 存放全局变量和静态变量- 初始化的全局变量和静态变量在一块区域
- 未初始化的全局变量、未初始化的静态变量在相邻的另一块区域
- 文字常量区 存放常量字符串
- 程序代码区 存放二进制代码