Data段存已初始化全局/静态变量,初值写入ELF .data节;BSS段存未初始化或零初始化变量,磁盘不占空间、加载时清零;Stack段自高向低增长,存函数调用数据,自动管理且易栈溢出。

Linux进程的内存布局中,Data段、BSS段和Stack段各自承担不同职责,位置、初始化方式和生命周期差异明显。理解它们的分布与行为,对调试内存问题、分析崩溃日志、规避栈溢出或未初始化变量风险至关重要。
Data段:已初始化的全局与静态变量存放区
Data段保存程序中显式初始化过的全局变量、静态变量(含局部static)。这些变量在编译时就确定了初始值,因此其初值被直接写入可执行文件(如ELF)的.data节中。进程加载时,系统将该节内容复制到内存,并映射为可读写区域。
- 例如:
int global_var = 42;、static char buf[64] = "hello";都落在Data段 - Data段大小在链接阶段固定,运行时不自动增长
- 注意:初始化为0的全局/静态变量不在此段,而是归入BSS段(更节省磁盘空间)
BSS段:未初始化或零初始化变量的占位区
BSS段(Block Started by Symbol)用于存放未显式初始化的全局变量、静态变量,以及显式初始化为0的变量。它在可执行文件中不占用实际空间(仅记录所需大小),加载时由内核统一清零并分配对应内存。
- 例如:
int uninit_global;、static int zeroed = 0;、char big_array[1024*1024];都进入BSS - 优势在于减小二进制体积;1MB未初始化数组在磁盘上几乎不占字节,但运行时仍占1MB内存
- 所有BSS变量在程序启动前已被置为0(或NULL),无需代码干预
Stack段:函数调用与临时数据的自动管理区
Stack段从高地址向低地址生长,由内核为每个线程分配固定上限(通常8MB,默认可调)。它用于存储函数参数、返回地址、寄存器现场、非static局部变量。分配与释放完全由CPU指令和编译器自动完成,无需手动干预。
- 每次函数调用,栈帧(stack frame)被压入;返回时自动弹出
- 局部变量如
int x = 5;、char tmp[256];都在栈上,作用域结束即失效 - 递归过深、大数组声明(如
char huge[1000000];)易导致栈溢出(SIGSEGV) - 栈内存物理页按需分配,未访问部分不占实际RAM
三者在虚拟地址空间中的相对位置
典型用户态布局(自低地址向高地址)为:
.text → .rodata → .data → .bss → heap(向上增长)→ unused gap → stack(向下增长)→ env/argv
- Data和BSS紧邻,均属静态数据区,位于堆之前、代码段之后
- Stack独立位于最高端,与heap之间保留足够空隙,防止二者意外碰撞
- ASLR机制会随机化stack起始地址和heap基址,但Data/BSS相对位置固定(因编译时确定)










