Memory Model¶
- 单线程下:对象在内存中如何存在、何时开始/结束生命周期、哪些访问是合法的
- 多线程下:不同线程看到同一块内存时,读写如何同步、什么叫数据竞争、编译器和 CPU 可以做哪些重排
C++ 对象按存储期大致分为 4 类:
- 自动存储期:函数内局部变量,进入作用域构造,离开作用域析构
- 静态存储期:全局变量、命名空间静态、函数内静态。程序启动到结束都可能存在
- 线程存储期:thread_local,每个线程一份实例
- 动态存储期:new/malloc 得到的内存,需手动释放或交给 RAII 管理
内存区域:
- 栈:存放函数调用上下文和自动变量,分配释放极快,由编译器和调用约定自动管理
- 堆:运行时动态分配的大块区域,生命周期灵活,但管理成本高,容易泄漏和碎片
- 全局/静态区:存放全局变量、静态变量,生命周期贯穿程序运行期
- 常量区(只读数据区):字符串字面量、只读常量等,通常不可写
- 代码区(文本段):机器指令本体
stack(栈):
- 分配释放由函数进出作用域自动完成。一般是连续内存,局部性好,速度快。空间通常较小(和平台、线程栈大小配置有关)
- 放函数参数、返回地址、保存寄存器。自动存储期局部变量(普通局部对象)
- 栈溢出:递归过深或大数组放栈上
- 悬空指针:返回局部变量地址
heap(堆):
- 运行时按需申请,大小和生命周期更灵活。分配释放慢于栈。可能出现内存碎片。需要正确管理所有权
- 放动态创建对象,大体量数据或跨作用域共享对象
- 内存泄漏:只分配不释放
- 重复释放:同一块内存释放多次
- 野指针:释放后继续访问
- 异常路径泄漏:中途抛异常没走到释放逻辑
全局/静态区:
- 放全局变量,静态变量(包括函数内静态),类静态数据成员
- 程序启动前初始化,程序退出时析构
常量区:字符串字面量通常在只读区域。试图修改会导致未定义行为或崩溃
代码区:存程序指令。一般可执行不可写(受平台保护策略影响)
评论区
欢迎在评论区指出文档错误,为文档提供宝贵意见,或写下你的疑问