1. GLIBC tcache机制
GLIBC自从2.26版本开始,增加了tcache( thread local caching)机制,旨在提高GLIBC内存管理性能。tcache机制利用了线程私有数据结构,以达到无锁状态下快速内存管理。tcache机制在编译时通过USE_TCACHE进行控制,默认是打开的。
在GLIBC中,将会为每个线程均维持一个tcache结构,入口为:MAYBE_INIT_TCACHE。结构如下:
typedef struct tcache_entry // tcache每个实体数据结构
{
struct tcache_entry *next;
struct tcache_perthread_struct *key;
} tcache_entry;
typedef struct tcache_perthread_struct // tcache原始数据结构
{
char counts[TCACHE_MAX_BINS];
tcache_entry *entries[TCACHE_MAX_BINS]; // TCACHE_MAX_BINS = 64,每个entry之间用有序单项链表进行维护,每个entries容器最多只能容纳7个成员,即链表长度为7。
} tcache_perthread_struct;
从上数据结构可知,每个线程的tcache拥有64个entries,每个entries都由成员数量为7的单项链表维护。
1.1. tcache每个entries成员数量的限制
static struct malloc_par mp_ =
{
.top_pad = DEFAULT_TOP_PAD,
.n_mmaps_max = DEFAULT_MMAP_MAX,
.mmap_threshold = DEFAULT_MMAP_THRESHOLD,
.trim_threshold = DEFAULT_TRIM_THRESHOLD,
#define NARENAS_FROM_NCORES(n) ((n) * (sizeof (long) == 4 ? 2 : 8)) //限制每个进程所拥有的arena数量(一般为CPU核数*2)
.arena_test = NARENAS_FROM_NCORES (1)
#if USE_TCACHE
,
.tcache_count = TCACHE_FILL_COUNT, //限制tcache每个entries成员的大小(默认为7)
.tcache_bins = TCACHE_MAX_BINS,
.tcache_max_bytes = tidx2usize (TCACHE_MAX_BINS-1),
.tcache_unsorted_limit = 0 /* No limit. */
#endif
};
1.2. tcache内存分配
在__libc_malloc函数中,tcache内存分配的优先级最高,即在malloc分配内存时,优先使用tcache中的内存,如果有满足条件的内存块存在,则直接返回;否则使用arena进行内存分配(后续介绍)。入口为:tcache_get。
1.3. tcache内存free
在_int_free中,当free内存时优先将小于等于1KB的内存块放入tcache bins中,直到64个bins都被fang放满,且每个bins中只能存放7个成员。入口为:tcache_put。
注:每个线程的tcache最多可分配228KB内存。