Glibc Malloc (PTMalloc) Overview
本文主要参考:https://sourceware.org/glibc/wiki/MallocInternals
简述
历史:glibc中使用的malloc即是从ptmalloc(pthread malloc)中演化得到的。
名词解释:
- Arena:在一个或多个thread之间共享,包含有对多个heap的引用和这些heap中空闲(free)的chunk的链表。分配到每个arena的线程会从这个空闲链表中分配内存。
- Heap:一段连续的内存,被分成了多个chunk。每一个heap只属于一个arena。
- Chunk:一小段内存,可以从这里分配、释放、或者和相邻的chunk合并为一个大段的内存。注意到chunk是分配到程序的一块内存的wrapper。每一个chuck存在于一个heap,且属于一个arena。
- Memory:程序的地址空间的一部分,一般背后实际上是RAM、或swap区域。
Chunk简介
glibc malloc将一大段内存(heap)分为不同size的多个chunk。每一个chunk包含一个mata-data指明这个chunk的size(通过chunk header的size数据),和相邻的chunk的位置。当一个chunk被程序使用时,记住的数据只有chunk的size。当chunk被释放时,之前存放程序数据的内存,将重新用来存放arena相关的额外信息。另外,一个被释放的chunk的最后一个word包含了一个chunk的size字段的拷贝。3个LSB(最低有效位)置为0。与之相反的是,chunk最前面的3个LSB是作为标志位来使用的。
chunk指针(mchunkptr)指向的不是chunk的开始位置,而是前一个chunk的最后一个word。
由于所有的chunk都是8B的倍数,chunk的size字段的3个LSB可以被用作标志位,其定义如下:
- A(0x04):被分配的区域。使用程序的heap的main arena。其他的区域使用的mmap的heap(使用mmap获得的内存的区域)。如果这个位是0,chunk来自于main arena、main heap。如果是1,chunk来源于mmap的内存,heap的位置可以通过chunk的地址来计算得到。
- M(0x02):mmap的chunk。这个chunk使用mmap的一个调用来分配的,不属于某个heap。
- P(0x01):前一个chunk正在被使用。如果置为1,程序还在使用前面一个chunk,
prev_size
字段无效。注意,一些chunk如在fastbin中的,也会设置这个位。这个位真实的意思是前一个chunk是否被考虑要作为合并的一部分。(此处的“合并”指的是将两个地址相邻的chunk合并为一个大的chunk。)
下图中的“prev_size”指的是前一个chunk的si