深入 C++内存管理
前言
说到 C++ 的内存管理,我们可能会想到 栈空间的本地变量、堆上通过 new 动态分配的变量以及全局命名空间的变量等,这些变量的分配位置都是由系统来控制管理的,而调用者只需要考虑变量的生命周期相关内容即可,而无需关心变量的具体布局。这对于普通软件的开发已经足够,但是对于引擎开发而言,我们必须对内存有着更为精细的管理。
1、基础概念
1.1 内存布局
内存分布(可执行映像)
一个C++程序的内存分布可分为:四部分
- Code Segment(代码区):也称为Text Segment,存放可执行程序的机器码
- Data Segment(数据区):存放已初始化的全局和静态变量,常量数据(如字符串常量)
- BSS(Block started by symbol):存放未初始化的全局和静态变量(默认设为0)
- Heap(堆):从低地址向高地址增长。容量大于栈,程序中动态分配的内存在此区域
- Stack(栈):从高地址向低地址增长。由编译器自动管理分配。程序中的局部变量、函数参数值、返回变量等存在此区域
1.2 函数栈
如上图所示,可执行程序的文件包含 BSS、Data、Segment 和 Code Segment,当可执行程序载入内存后,系统会保留一些空间,即堆区和栈区。堆区主要是动态内存分配的内存(默认情况下),而栈区主要是函数以及局部变量等(包括main函数)。一般而言,栈的空间小于堆的空间
当调用函数时,一块连续的内存(堆栈帧)压入栈;函数返回时,堆栈帧弹出
堆栈帧包含如下数据:
- 函数返回地址
- 局部变量 / CPU寄存器数据备份
1.3 全局变量
当全局 / 静态变量(如下代码中的x和y变量)未初始化的时候,它们记录在 BSS 段
int x;
int z = 5; // 存储于数据段