fast bins、unsorted bins、malloc state

FastBins

大小在(64位平台)0x20~0x80之间,当chunk的大小在fastbin之间的时候,当释放时,会直接放入fastbin中。

fastbin是用fd来进行遍历的,所遵循的数据结构是后进先出(fd代表下一个chunk的地址)

malloc

如果申请的 chunk 的大小位于 fastbin 范围内,需要注意的是这里比较的是无符号整数。此外,是从 fastbin 的头结点开始取 chunk。

 1     /*
 2        If the size qualifies as a fastbin, first check corresponding bin.
 3        This code is safe to execute even if av is not yet initialized, so we
 4        can try it without checking, which saves some time on this fast path.
 5      */
 6 
 7     if ((unsigned long) (nb) <= (unsigned long) (get_max_fast())) {
 8         // 得到对应的fastbin的下标
 9         idx             = fastbin_index(nb);
10         // 得到对应的fastbin的头指针
11         mfastbinptr *fb = &fastbin(av, idx);
12         mchunkptr    pp = *fb;
13         // 利用fd遍历对应的bin内是否有空闲的chunk块,
14         do {
15             victim = pp;
16             if (victim == NULL) break;
17         } while ((pp = catomic_compare_and_exchange_val_acq(fb, victim->fd,
18                                                             victim)) != victim);
19         // 存在可以利用的chunk
20         if (victim != 0) {
21             // 检查取到的 chunk 大小是否与相应的 fastbin 索引一致。
22             // 根据取得的 victim ,利用 chunksize 计算其大小。
23             // 利用fastbin_index 计算 chunk 的索引。
24             if (__builtin_expect(fastbin_index(chunksize(victim)) != idx, 0)) {
25                 errstr = "malloc(): memory corruption (fast)";
26             errout:
27                 malloc_printerr(check_action, errstr, chunk2mem(victim), av);
28                 return NULL;
29             }
30             // 细致的检查。。只有在 DEBUG 的时候有用
31             check_remalloced_chunk(av, victim, nb);
32             // 将获取的到chunk转换为mem模式
33             void *p = chunk2mem(victim);
34             // 如果设置了perturb_type, 则将获取到的chunk初始化为 perturb_type ^ 0xff
35             alloc_perturb(p, bytes);
36             return p;
37         }
38     }

 

unsorted bins

unsorted bin是small bin和large bin的一个cache,small bin在释放的时候,会先放入unsorted bin中,在unsorted中没有适合块时,unsorted bin会把chunk放入其所属的bin中,然后在适合的bin中分配chunk,如果还没有适合的chunk,就会进行chunk的合并,合并之后,若还没有相应的chunk,就会向top chunk来申请内存。Bins 数组中的元素 bin[1]用于存储 unsorted bin 的 chunk 链表头。

如果在分配unsorted bins时,但有合适的块,但比需要的块要大,就会进行切割,切割后,剩余的chunk依旧会在unsorted bin中

 

malloc state

每个分配区是 struct malloc_state 的一个实例,ptmalloc 使用 malloc_state 来管理分配区,而参数管理使用 struct malloc_par,全局拥有一个唯一的 malloc_par 实例。

struct malloc_state {
 /* Serialize access. */
 mutex_t mutex;
 
 /* Flags (formerly in max_fast). */
 int flags;
#if THREAD_STATS
 /* Statistics for locking. Only used if THREAD_STATS is defined. */
 long stat_lock_direct, stat_lock_loop, stat_lock_wait;
#endif
 
 /* Fastbins */
 mfastbinptr fastbinsY[NFASTBINS];
 
 /* Base of the topmost chunk -- not otherwise kept in a bin */
 mchunkptr top;
 
 /* The remainder from the most recent split of a small request */
 mchunkptr last_remainder;
 
 /* Normal bins packed as described above */
 mchunkptr bins[NBINS * 2 - 2];
 
 /* Bitmap of bins */
 unsigned int binmap[BINMAPSIZE];
 
 /* Linked list */
 struct malloc_state *next;
 
#ifdef PER_THREAD
 /* Linked list for free arenas. */
 struct malloc_state *next_free;
#endif
 
 /* Memory allocated from the system in this arena. */
 INTERNAL_SIZE_T system_mem;
 INTERNAL_SIZE_T max_system_mem;
};
 

Mutex:用于串行化访问分配区,当有多个线程访问同一个分配区时,第一个获得这个 mutex 的线程将使用该分配区分配内存,分配完成后,释放该分配区的 mutex,以便其它线程使用该分配区。

Flags:记录了分配区的一些标志,bit0 用于标识分配区是否包含至少一个 fast bin chunk,bit1 用于标识分配区是否能返回连续的虚拟地址空间。

fastbinsY:拥有 10(NFASTBINS)个元素的数组,用于存放每个 fast chunk 链表头指针,所以 fast bins 最多包含 10 个 fast chunk 的单向链表。

top:一个 chunk 指针,指向分配区的 top chunk。

last_remainder:是一个 chunk 指针,分配区上次分配 small chunk 时,从一个 chunk 中分裂出一个 small chunk 返回给用户,分裂后的剩余部分形成一个 chunk,last_remainder 就是指向的这个 chunk。

binmap:一个 int 数组,ptmalloc 用一个 bit 来标识该 bit 对应的 bin 中是否包含空闲 chunk。

 

posted @ 2020-10-26 23:59  PYozo_free  阅读(563)  评论(0编辑  收藏  举报