workspace/tags/glibc/
Glibc
- 2.4x 的 tcache 机制分析
简述
在 2.39 到 2.40 中,malloc.c 并未发生变化,因此我们这里主要讲一些 2.41 到 2.43 的 tcache 相关的一些小细节 在这三个版本中,主要变化可以简单概括为
- 2.41:
- calloc 可以分配 tcache 块
- 小 chunk 被 free 后会直接进入 small bin
- 2.42
- large_tcache 的引入
- 2.43
- tcache 扩容以补偿 fastbin 删除的性能问题
- large_tcache 分配改为需要精确 chunk_size
- mmap chunk 可以进入 tcache
因为 tcache 初始化时机这几个版本一直改来改去的很乱,只做简述 以下为细分的分析,我会粘贴一些源码辅助理解
tcache 基本机制
tcache 结构体的变化
在 glibc 2.42版本中,tcache_perthread_struct 结构进行了调整
- 2.41
/* We overlay this structure on the user-data portion of a chunk when the chunk is stored in the per-thread cache. */ typedef struct tcache_entry { struct tcache_entry *next; /* This field exists to detect double frees. */ uintptr_t key; } tcache_entry; /* There is one of these for each thread, which contains the per-thread cache (hence "tcache_perthread_struct"). Keeping overall size low is mildly important. Note that COUNTS and ENTRIES are redundant (we could have just counted the linked list each time), this is for performance reasons. */ typedef struct tcache_perthread_struct { uint16_t counts[TCACHE_MAX_BINS]; tcache_entry *entries[TCACHE_MAX_BINS]; } tcache_perthread_struct; static __thread bool tcache_shutting_down = false; static __thread tcache_perthread_struct *tcache = NULL;- 2.42
/* We overlay this structure on the user-data portion of a chunk when the chunk is stored in the per-thread cache. */ typedef struct tcache_entry { struct tcache_entry *next; /* This field exists to detect double frees. */ uintptr_t key; } tcache_entry; /* There is one of these for each thread, which contains the per-thread cache (hence "tcache_perthread_struct"). Keeping overall size low is mildly important. The 'entries' field is linked list of free blocks, while 'num_slots' contains the number of free blocks that can be added. Each bin may allow a different maximum number of free blocks, and can be disabled by initializing 'num_slots' to zero. */ typedef struct tcache_perthread_struct { uint16_t num_slots[TCACHE_MAX_BINS]; tcache_entry *entries[TCACHE_MAX_BINS]; } tcache_perthread_struct;entry 的部分基本没有变化,这里主要变化还是原本的 counts 数组变成了 num_slots 数组 原本的 counts 数组表示对应索引下 tcache 链表的长度,现在 num_slots 数组中变为了对应索引下设剩下的空槽位
- 2.41:
Terminal
C0nvR3 Lab terminal ready. Type help for commands.