目前市面上有不少分析Jemalloc老版本的博文,但最新版本5.3.0却少之又少。而且5.3.0的架构与5之前的版本有较大不同,本着“与时俱进”、“由浅入深”的宗旨,我将逐步分析最新release版本Jemalloc5.3.0的实现。
另外,单讲实现代码是极其枯燥的,我将尽量每个原理知识点都用一个简简单单的小程序引出,这样便于大家测试和上手调试。另外,我还会用GDB打印数据结构、变量的值,方便理解当时的状态或算法。
为了减少不同线程间的竞争,Jemalloc为每个线程配备了其专属的“布袋”(tcache,估计是thread cache的缩写)用来缓存一些立即可用的内存,而且布袋又分成了很多隔间(bin数组)用来区分不同大小的内存,比如bins[0]是8个字节大小的空闲内存,bins[1]是16个字节大小的空闲内存。。。,还是上节size class的那套。
注意: 此处的bins类型为cache_bin_t, 与arena_t中的bins类型bin_t不同。
来一个小程序试试手
//gcc tcache.c `jemalloc-config --libdir`/libjemalloc.a `jemalloc-config --libs` -g
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char* argv[])
{
void *p1= malloc(10);
memset(p1,'a',10);
void *p2=malloc(10);
memset(p2,'b',10);
free(p1);
free(p2);
return 0;
}
在第二个malloc下断点(第一个malloc比较复杂,需要先给tcache.bin[1]填充一梭子弹药,第二个malloc只需直接取子弹),慢慢单步
让我们先直接看看用户是怎么得到内存的:361行ret就是返给用户的内存地址(p2, 我的机器上是0x7ffff741d010), stack_head中藏着重点。说句题外话:stack_head-1指向的内存值就是p1(已被使用)。
下面让我们把stack_head, stack_head-1指向的内存的值打出来。
看着熟悉吧,分别是第一次和第二次malloc返给用户的结果。
可以想像,当free p1时是反向操作,即:stack_head往小(地址)方向移动,并把要释放的内存的地址赋给stack_head指向的格子。
cache_bin_alloc/cache_bin_dalloc都只是挪了下stack_head而已。请看下图理解这些过程。
好了,因为是“浅”说,就点到为止吧。
标签:bin,head,p1,--,malloc,九浅,一深,内存,stack From: https://blog.csdn.net/zhaiminlove/article/details/139653608