理解 Heap
high address +---------------+
| |
| Stack |
| |
+---------------+
| | |
| v |
| |
| |
+---------------+
| Mmap |
+---------------+
| |
| |
| ^ |
| | |
+---------------+
| |
| Heap |
| |
+---------------+
| Data |
+---------------+
| Code |
low address +---------------+
上图是 Linux 进程的地址空间,从低位到高位地址分别为:
- Code Segment: 程序的代码,CPU 执行的指令部分,共享只读。
- Data Segment: 可细分为初始化数据段和未初始化数据段,常用于存储全局变量等。
- Stack: 函数以及自动变量(未加 static 的自动变量又称为局部变量)。
- Mmap: mmap 调用分配的地址空间。
- Heap: 动态分配内存,如 malloc() 分配的内存。
本文主要讲解 heap,从上图可知,进程的堆是一段连续的空间,它分为三个区域:
- Mapped region: 该区域的空间已经在物理地址上分配,可以直接被程序使用。
- Unmapped region: 该区域的空间未在物理地址上分配,需分配后才可以使用。
- Unusable region: 不可使用的地址空间,超出 rlimit 的空间都是不可使用的,不同的硬件和操作系统下,rlimit 可能各不相同。
其中 break 和 rlimit 是三个区域的分界线:
- break: mapped region 和 unmapped region 的分界线,可调用 sbrk(0) 返回当前的 break。
- rlimit: 堆能分配的最大地址空间,getrlimit(2) 可获取 rlimit。
- start of heap: 堆的起始地址,当堆上从未开辟空间时,sbrk(0) 返回的就是堆的起始地址,也可在 /proc/{proc_id}/mapping 获取堆的起始地址。
Heap
high address +-------------------+
| |
| Unusable Region |