线程缓存TCMalloc.docxVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
线程缓存TCMalloc

TCMalloc:线程缓存的Malloc 作者:Sanjay Ghemawat, Paul Menage 翻译:HYPERLINK /ShiningRay 动机 TCMalloc要比glibc 2.3的malloc(可以从一个叫作ptmalloc2的独立库获得)和其他我测试过的malloc都快。ptmalloc在一台2.8GHz的P4机器上(对于小对象)执行一次malloc及free大约需要300纳秒。而TCMalloc的版本同样的操作大约只需要50纳秒。malloc版本的速度是至关重要的,因为如果malloc不够快,应用程序的作者就很有可能在malloc之上写一个自己的HYPERLINK /wiki/Free_list \o Free list自由列表。这就可能导致额外的代码复杂度,以及更多的内存占用――除非作者本身非常仔细地划分自由列表的大小并经常从自由列表中清除空闲的对象。 TCMalloc也减少了多线程程序中的锁争用情况。对于小对象,几乎已经达到了零争用。对于大对象,TCMalloc尝试使用粒度较好和有效的自旋锁。ptmalloc同样是通过使用每线程各自的场地来减少锁争用,但是ptmalloc2使用每线程场地有一个很大的问题。在ptmalloc2中,内存可能会从一个场地移动到另一个。这有可能导致大量空间被浪费。例如,在一个Google的应用中,第一阶段可能会为其URL标准化的数据结构分配大约300MB内存。当第一阶段结束后,第二阶段将从同样的地址空间开始。如果第二个阶段被安排到了一个与第一阶段什?用的场地不同的场地,这个阶段不会复用任何第一阶段留下的的内存,并会给地址空间添加另外一个300MB。类似的内存爆炸问题也可以在其他的应用中看到。 TCMalloc的另一个好处是小对象的空间最优表现形式。例如,分配N个8字节对象可能要使用大约8N * 1.01字节的空间。即,多用百分之一的空间。而ptmalloc2中每个对象都使用了一个四字节的头,(我认为)并将最终的尺寸规整为8字节的倍数,最后使用了16N字节。 使用 要使用TCMalloc,只要将tcmalloc通过“-ltcmalloc”链接器标志接入你的应用即可。 你也可以通过使用LD_PRELOAD在不是你自己编译的应用中使用tcmalloc: $ LD_PRELOAD=/usr/lib/libtcmalloc.so LD_PRELOAD比较讨巧,我们也不十分推荐这种用法。 TCMalloc还包含了一个HYPERLINK /svn/trunk/doc/heap_checker.html \o heap checker堆检查器以及一个 HYPERLINK /svn/trunk/doc/heapprofile.html \o heap profiler 堆测量器。 如果你更想链接不包含堆测量器和检查器的TCMalloc版本(比如可能为了减少静态二进制文件的大小),你可以接入libtcmalloc_minimal。 概览 TCMalloc给每个线程分配了一个线程局部缓存。小分配可以直接由线程局部缓存来满足。需要的话,会将对象从中央数据结构移动到线程局部缓存中,同时定期的垃圾收集将用于把内存从线程局部缓存迁移回中央数据结构中。 TCMalloc将尺寸小于= 32K的对象(“小”对象)和大对象区分开来。大对象直接使用页级分配器(一个页是一个4K的对齐内存区域)从中央堆直接分配。即,一个大对象总是页对齐的并占据了整数个数的页。 连续的一些页面可以被分割为一系列小对象,而他们的大小都相同。例如,一个连续的页面(4K)可以被划分为32个128字节的对象。 小对象的分配 每个小对象的大小都会被映射到170个可分配的尺寸类别中的一个。例如,在分配961到1024字节时,都会归整为1024字节。尺寸类别这样隔开:较小的尺寸相差8字节,较大的尺寸相差16字节,再大一点的尺寸差32字节,如此类推。最大的间隔(对于尺寸 = ~2K的)是256字节。 一个线程缓存对每个尺寸类都包含了一个自由对象的单向链表。 当分配一个小对象时: 我们将其大小映射到对应的尺寸类中。 查找当前线程的线程缓存中相应的自由列表。 如果自由列表不空,那么从移除列表的第一个对象并返回它。当按照这个快速通道时,TCMalloc不会获取任何锁。这就可以极大提高分配的速度,因为锁/解锁操作在一个2.8GHz Xeon上大约需要100纳秒的时间。 如果自由列表为空: 从该尺寸类别的中央自由列表(中央自由列表是被所有线程共享的)取得一连串对象。 将他们放入线程局部的自由列表。 将新获取的对象中的一个返回给应用程序。 如果中央自由列表也为空:(1) 我们从中央页分配器分配了一连串页面。(2) 将他们分割成该

文档评论(0)

haihang2017 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档