码迷,mamicode.com
首页 > 其他好文 > 详细

tcmalloc原理分析

时间:2019-10-18 11:06:13      阅读:151      评论:0      收藏:0      [点我收藏+]

标签:保存   编程思想   应该   优秀   回收   要求   释放   www   阶段   

  1. tcmalloc(即Thread-Cache Malloc)是一个通用的内存分配器,使用tcmalloc只需要在编译的链接阶段加入-ltcmalloc,而不是使用glibcptmalloc2),不需要有任何的代码改动。也就是说用户在使用malloc/freenew/delete时会使用tcmalloc进行内存分配。

  2. 为什么要使用tcmalloc

主要是因为性能,tcmalloc能提供更快的申请/释放速度,而且内存利用率更高,产生更少的内存碎片

  1. 原理:先上图

技术图片

    1. 基本概念:

Free List:数组链表,链表中保存了内存块

objects:内存块

Page:页内存,内存分隔成大小固定,地址对齐的块

Spantcmalloc管理内存的单位,一个Span可以包含一个或多个Page

Radix Tree:基数树,是一种广泛用于内存管理的数据结构,这里用来管理Span

?

    1. 组织结构:

tcmalloc256k为界将内存分成大块内存和小块内存,使用不同的策略分别对这两种内存进行管理。从图中可以看到,tcmalloc由若干(线程数)个Thread Cache,一个Central Heap和一个Page Heap组成。这三种结构中都包含一个数组,而数组的元素是一个链表。数组链表是tcmalloc管理内存的主要数据结构之一。三者所不同的是,Thread Cache的链表(FreeList)内容是object,是被切分的小的内存块;Central HeapFreeList)和Page HeapSpanList)的链表内容是Span,但Central HeapSpan中又有切分的object

    1. 小内存的分配策略

小内存的管理由两部分构成:Thread CacheCentral Heap。其中Thread Cache是线程本地Cache,每个线程一个;Central Heap则由所有线程共享。

当一个线程申请内存时,首先响应的是Thread Cache,如 大专栏  tcmalloc原理分析果其中有足够大的内存满足要求,可直接返回。只有当内存不够时,需要向Central Heap申请,此时使用了一个细粒度的自旋锁来保证线程安全。如果Central Heap没有足够内存该怎么办呢,后面会讲到具体策略。

?

由上可知,小内存的分配在大部分情况下都是预分配好的,可以拿来即用,只有在本地Cache不足的情况才需要加锁,因此效率很高。

    1. 大内存的分配策略

大内存通过Page Heap来管理内存,策略与小内存相似,也是预分配好一个数组链表,不同的是Page Heap只有一个,而且实际上Central HeapSpan也是从Page Heap上分配出去的。

Page Heap的数组共256项,每项中的Span依次包含1-255Page,最后一项的Span包含大于等于256Page。当数组中的第k项已经没有Span时,可以从第k+1项拿一个Span,将这个Span拆成一个包含kPageSpan提供给申请者,一个包含1项的Span放到数组的第1项中。如果第k+1项同样没有Span则继续项第k+2项申请,依次类推。

    1. 内存回收

???????? 当释放一个内存对象时,需要先根据地址计算出页号,再在Radix Tree中找到页号对应的Span,根据Span确定是小内存还是大内存对象。
???????? 如果是小内存,需要把它插入内存本地的FreeList中,如果线程本地内存cache超过阈值(默认2MB),会使用策略将部分未使用的内存块移动到Central Heap中,此时放到了central cache中的tc_slots_中,而不是直接放入Span中,只有当tc_slots_满了,才会归还到Span中,这样的好处是在Thread Cache和Central Heap中又加入了一层缓存使效率更高。
???????? 如果是大内存,还要获取这个Span页的前一页和后一页是否空闲,如果都不空闲,则直接将这个Span放入SpanList合适的位置,如果这个Span的前一页或后一页存在空闲,还需要将这个Span与前面或后面的Span合并后再把新的Span放入合适的SpanList中。例如,Span1包含[m, n-1]页,Span2包含[n, k-1]页,Span3包含[k, s]页,此时回收了Span2,如果检查发现第n-1页空闲,第k页非空闲,此时需要将Span1和Span2合并成一个包含[m, k-1]页的新Span,而如果第n-1页和第k页都空闲的话,则合并后的新Span应包含[m,s]页。
4.?? ?后记
???????? 使用tcmalloc后,不必再费尽心思去在代码中设计内存池,而且使用时不需要包含任何头文件,只需要在链接环节使用-ltcmalloc代替glibc即可,这是作为一款通用内存管理器的便捷之处。同时在效率上可以得到数倍的提升。
???????? 其实tcmalloc中还有很多细节值得研究,我们应该学习其中优秀的编程思想,同时也希望通过以上分析对理解tcmalloc有所帮助。

?

?

tcmalloc原理分析

标签:保存   编程思想   应该   优秀   回收   要求   释放   www   阶段   

原文地址:https://www.cnblogs.com/wangziqiang123/p/11696929.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!