tcmalloc 要点

来源:互联网 发布:淘宝号半实名是啥意思 编辑:程序博客网 时间:2024/06/07 09:50

google.tcmalloc

线程缓存(threadcache)

加锁(locking)

加锁的开销是比较大的(cpu要同步cache),一般要几十个时钟周期,特别是cpu较多的时候,锁冲突概率大大增加。

malloc

不是在进入malloc就马上加锁,而是在thread cache耗尽后才加锁(用于从全局堆获取内存),加锁的频率被大大降低(通常情况下是几百倍)。

free

不是在每次free时都加锁,而是在free导致local cache空闲出整页内存时,才加锁将内存页交还给全局堆(globalheap)

radix-tree

tcmalloc使用的中心数据结构是radix-tree,这是trie-tree的一个变种。tcmalloc中的radix-tree更是大幅简化,相当于多层页表,32位环境下是2层,64位环境下是3。这样,对一个指针的查找可以在O(1)的时间内完成,并且可以查找范围(在合并内存页时是必须的)。

Hash也是O(1),但是Hash不能按范围查找,再加上其它一些缺陷(hash冲突、rehashO(1)的常数项也较大等)hash不适合tcmalloc

按尺寸分组

对小于一定尺寸(32K)malloc,每种尺寸在一些连续的内存页上分配。这被称为size-class,每种尺寸并不是完全等距的,请求的尺寸会按一定规则对齐到下一个size-class

使用size-classmalloc出的内存就不需要在相邻的内存上(紧邻在malloc出来的内存之前)做簿记(bookkeeping)了。传统的malloc需要这样的簿记,以便free时能找到链接的块,并且得到正确的内存大小。

使用size-class不但可以省掉额外的内存消耗,并且,可以size-class对齐

malloc时,按请求的尺寸查找相应的size-class,如果大于max-size-class32k),就直接从全局堆分配,并且总是页对齐的。

  free时,在radix-tree中查找free的内存地址,得到其所属的spanspan就是一块连续多个页的内存),进而得到其它信息(如size-class等,如果是大块内存则直接从全局堆free)。对于小块内存,大多数情况下,剩下的事情就是一个简单的链表操作。如果这次free导致整个span空闲,就将span回收。

总结

tcmalloc的巨大优势:

  • 线程缓存,大幅减少了加锁,更有效利用cpucache

  • 使用size-class,减少了小块内存的book-keeping,并且能更好地对齐。

  • 总的开销更低

 

其他相关文档

http://code.google.com/p/google-perftools/

GeneralInformation and Documentation

tcmalloc.htmldocumentation in Chinese (against perftools 0.94)

 

 

原创粉丝点击