tcmalloc简单介绍

github 地址
thread-caching malloc
与标准库glibc的malloc相比,tcmalloc的分配速度和效率都要高,在并发情况下性能上有提升。
实现原理的简单介绍:
(1)每个线程分配一个单独的cache,小对象可直接在线程cache上进行分配,避免使用锁
(2)大对象直接在堆上进行分配
具体介绍见TCMalloc : Thread-Caching Malloc
基本意思如下:
TcMalloc比glibc 2.3 malloc(或者ptmalloc2)以及其他的一些内存分配器要快。
在分配小对象时,ptmalloc2执行一次分配和回收大概花费300ns(2.8 GHz P4机器)。执行同样的操作,tcmalloc大概只需要50ns。
对于多线程程序来说,tcmalloc减少了锁的争用。对于小对象,几乎是零竞争。对于大对象的分配来说,tcmalloc会尝试采用细粒度的自旋锁。ptmalloc2也是通过对每个线程分配arena来减少竞争,但是ptmalloc2存在arena不能移动的问题,有时候会导致比较大的内存浪费。
tcmalloc对每个线程分配本地cache,当满足分配条件时,小对象直接在本地cache上进行分配。当本地cache空间不足时,可从central中分配内存到本地cache,周期gc会将空闲的本地cache空间返还给central。
小于等于32K的对象为小对象,大于32K的为大对象。大对象直接在堆上分配,以page为单位,每个page大小为4K。多个page可用于分配多个小对象。例如一个page(4K),可以用于分配32个128字节大小的对象。
小对象的分配:
按照class-size,划分了大概170种小对象。每个thread cache按照class-size,都保存了一条空闲对象的单向链表。
当分配小对象时,首先根据要分配的大小找到合适的class-size,然后在thread cache对应class-size的链表上寻找合适的分配对象。如果链表不空,返回第一个空闲对象即可。在这种情况下,不会出现锁竞争的情况,加速分配速度。因为加锁/解锁大概会花费100ns的时间。
如果链表为空,从central对应class-size的free list获取一些空闲对象给thread cache,然后返回一个空闲对象。central是线程共享的。
如果centra free list也为空,则从central page中获取一些pages,根据class-size进行划分,分给central free list,同样也分配一些对象给thread cache。
大对象的分配:
central page是按照page的数量进行划分的,page的数量从1个到255个,大于等于256个page由一个free list进行管理。
在对应的page free list寻找空闲对象时,如果没有空闲对象,如下一个page free list寻找,直到找到为止。如果找遍page free list都没有,则向系统申请。
连续的pages称为span,span可以分配和释放。
。。。

分配思路和go的分配基本一致。

你可能感兴趣的:(tcmalloc)