TCMalloc(Thread-Caching Malloc) 笔记

TCMalloc(Thread-Caching Malloc) 笔记

推荐直接看英文原版介绍,比国内的论坛介绍要详细的多,文末有链接地址。
  • 在介紹TCMalloc原理之前,需要知道为什么会出现这个?是为了解决什么问题?应用于什么场景?

    • malloc创建和free内存不够快,基于glibc 2.3的malloc,依赖于ptmalloc2,在2.8GHz Process4的机器上,创建小对象(大小小于等于32K),大致需要300ns,而对于tcmalloc来说,只需要大约50ns。所以速度快。

    • 多线程中,tcmalloc可以减小锁竞争,对于小对象来说,几乎零竞争,而对于大对象来说,tcmalloc会尝试使用细粒度和高效的自旋锁;而malloc,ptmalloc2在创建每个线程时候,会为每个线程分配空间,有一个问题就是,线程之前的内存是不会重复利用的;举例来说,一个应用程序,在第一阶段为它的数据结构分配了大约200MB的内存,当第一个阶段完成之后,第二个阶段会在相同的地址空间启动,如果第二个阶段分配的内存区域和第一个阶段分配的区域是不同的,那么第一个阶段的剩余内存,第二阶段是不会利用的,会重新分配200MB的内存,导致空间的浪费。

    • 效率,tcmalloc对于小对象的空间的利用率更高,比如当需要使用空间为8N*1.01bytes的内存空间,那么tcmalloc只需要创建8N bytes的对象,也就是说有百分之1的空间开销。而ptmalloc2则需要使用16N bytes。

      注意敲黑板划重点了(熊猫头)_黑板_熊猫_注意_重点表情

  • TCMalloc工作原理是什么?

    ​ TCMalloc为每个线程分配一个线程本地缓存。线程本地缓存满足了较小的分配。根据需要将对象从中心数据结构移动到线程本地缓存中,并使用定期的垃圾收集将内存从线程本地缓存迁移回中心数据结构中。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yZWj4KMr-1597048864592)(C:\Users\Tj\AppData\Roaming\Typora\typora-user-images\1597047088342.png)]

TCMalloc计算大小<= 32K的对象(小对象 small object)与计算较大的对象不同。使用页面级分配器从中央堆直接分配给大对象(页面是4K对齐的内存区域)。即。,一个大对象总是页面对齐的,并且占用整数倍的页面数量。

当然,也可以将页面分割成一系列大小相同的小对象。例如,一个页面(4K)的运行可以分割成32个对象,每个对象的大小为128字节。

分配的话: 分为小对象,和大对象的分配:

  1. 小对象:

    每个小对象大小映射到大约170个可分配大小类中的一个。例如,范围961到1024字节的所有分配都被四舍五入到1024。size类的间距是这样的:小的大小用8个字节隔开,大的大小用16个字节隔开,甚至大的大小用32个字节隔开,以此类推。最大的间距(对于大小>= ~2K)是256字节。

     线程缓存包含每个大小类的单独的空闲对象链表。 如图所示:
    

    在这里插入图片描述

    当分配一个小对象时:(1)我们将其大小映射到相应的size-类。(2)查找当前线程在线程缓存中对应的空闲列表。(3)如果空闲列表不是空的,我们从列表中删除第一个对象并返回它。当遵循这个快速路径时,TCMalloc根本不需要锁。这有助于显著提高分配速度,因为在2.8 GHz的Xeon上,一个锁/解锁对大约需要100纳秒。

    ​ 如果空闲列表为空:(1)我们从这个大小类的中心空闲列表中获取一组对象(该中心空闲列表由所有线程共享)。(2)将它们放在线程本地空闲列表中。(3)将一个新获取的对象返回给应用程序。

    ​ 如果中央空闲列表也是空的:(1)我们从中央页面分配器申请对页面的管理。(2)将获得的页面分割为这个size类的一组对象。(3)将新对象放在中央空闲列表中。和前面一样,将其中一些对象移动到线程本地空闲列表中。

  2. 大对象:

    大对象大小(> 32K)被舍入到页面大小(4K),并由中央页面堆处理。中央页面堆也是空闲列表的数组。对于i < 256,第k个条目是一个由k个页面组成的运行的空闲列表。第256项是长度为>= 256页的运行的自由列表,如图所示:
    在这里插入图片描述

​ 通过查找第k个空闲列表来满足k个页面的分配。如果这个空闲列表是空的,我们就会查看下一个空闲列表,以此类推。最后,如果需要,我们会查看最后一个空闲列表。如果失败,我们从系统中获取内存(使用sbrk、mmap或映射/dev/mem的部分)。

	如果运行长度为> k的页面满足k个页面的分配,则将剩余的运行时间重新插入到页面堆中适当的空闲列表中 。

跨度:

	TCMalloc管理的堆由一组页面组成。连续页面的运行由Span对象表示。可以分配span,也可以释放span。如果空闲,则span是页面堆链表中的一个条目。如果被分配,它要么是传递给应用程序的大对象,要么是分割成一系列小对象的页面运行。如果分割成小的对象,则对象的大小类将记录在span中。 

可以使用按页号索引的中央数组来查找页所属的跨度。例如,下面跨度a占用2页,跨度b占用1页,跨度c占用5页,跨度d占用3页
在这里插入图片描述

一个32位的地址空间可以容纳2^20个4K页面,因此这个中央数组需要4MB的空间,这似乎是可以接受的。在64位机器上,我们使用3级基数树而不是数组来从页号映射到相应的span指针。

参考:TCMalloc

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值