0%

Ptmalloc源码分析:arena

Ptmalloc源码分析:arena

我们知道一个线程申请的 1个/多个 堆包含很多的信息:二进制位信息,多个 malloc_chunk 信息等这些堆需要东西来进行管理,那么Arena就是来管理线程中的这些堆的

  • 一个线程只有一个 arnea,并且这些线程的arnea都是独立的不是相同的
  • 主线程的 arnea 称为 “main_arena”,子线程的arnea称为 “thread_arena”

libc-2.23

  • 管理 chunk 的结构体:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
typedef struct malloc_chunk* mchunkptr;

struct malloc_chunk {

INTERNAL_SIZE_T mchunk_prev_size; /* Size of previous chunk (if free). */
INTERNAL_SIZE_T mchunk_size; /* Size in bytes, including overhead. */

struct malloc_chunk* fd; /* double links -- used only if free. */
struct malloc_chunk* bk;

/* Only used for large blocks: pointer to next larger size. */
struct malloc_chunk* fd_nextsize; /* double links -- used only if free. */
struct malloc_chunk* bk_nextsize;
};
  • 管理 arena 的结构体:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# define NBINS 128

#ifndef INTERNAL_SIZE_T /* 判断是否定义INTERNAL_SIZE_T */
# define INTERNAL_SIZE_T size_t
#endif

struct malloc_state
{
mutex_t mutex; /* 同步访问相关,互斥锁(用来保证同步) */

int flags; /* 标志位(表示一些当前arena的特征) */

mfastbinptr fastbinsY[NFASTBINS]; /* Fastbins */

mchunkptr top; /* Top chunk */

mchunkptr last_remainder; /* 一个小请求的最近拆分的剩余部分 */

mchunkptr bins[NBINS * 2 - 2]; /* 常规bins chunk的链表数组 */

/* 因为每个bin链在bins数组中存储的是一个指针fd指针和一个bk指针,所以要NBINS*2 */
/* 又因为数组bins中索引为0,1的指针是不使用的,所以要减去2 */
/* 下标1是unsorted bin,2-63是small bin,64-126是large bin,共126个bin */

unsigned int binmap[BINMAPSIZE]; /* Bitmap of bins(一个循环单链表) */
/* 表示bin数组当中某一个下标的bin是否为空,用来在分配的时候加速 */

struct malloc_state *next; /* 分配区全局链表 */

struct malloc_state *next_free; /* 分配区空闲链表 */

INTERNAL_SIZE_T attached_threads; /* 连接到此arena的线程数 */

INTERNAL_SIZE_T system_mem; /* 用来跟踪当前被系统分配的内存总量 */
INTERNAL_SIZE_T max_system_mem; /* 最多从该arena的系统分配的内存大小 */
};