转自:http://blog.csdn.net/chosen0ne/article/details/9338591

版权声明:本文为博主原创文章,未经博主允许不得转载。

周末抽空看了一下tcmalloc,了解了个大概。下面记录一下。

一. 原理

tcmalloc就是一个内存分配器,管理堆内存,主要影响malloc和free,用于降低频繁分配、释放内存造成的性能损耗,并且有效地控制内存碎片。glibc中的内存分配器是ptmalloc2,tcmalloc号称要比它快。一次malloc和free操作,ptmalloc需要300ns,而tcmalloc只要50ns。同时tcmalloc也优化了小对象的存储,需要更少的空间。tcmalloc特别对多线程做了优化,对于小对象的分配基本上是不存在锁竞争,而大对象使用了细粒度、高效的自旋锁(spinlock)。分配给线程的本地缓存,在长时间空闲的情况下会被回收,供其他线程使用,这样提高了在多线程情况下的内存利用率,不会浪费内存,而这一点ptmalloc2是做不到的。

tcmalloc区别的对待大、小对象。它为每个线程分配了一个线程局部的cache,线程需要的小对象都是在其cache中分配的,由于是thread local的,所以基本上是无锁操作(在cache不够,需要增加内存时,会加锁)。同时,tcmalloc维护了进程级别的cache,所有的大对象都在这个cache中分配,由于多个线程的大对象的分配都从这个cache进行,所以必须加锁访问。在实际的程序中,小对象分配的频率要远远高于大对象,通过这种方式(小对象无锁分配,大对象加锁分配)可以提升整体性能。

线程级别cache和进程级别cache实际上就是一个多级的空闲块列表(Free List)。一个Free List以大小为k bytes倍数的空闲块进行分配,包含n个链表,每个链表存放大小为nk bytes的空闲块。在tcmalloc中,<=32KB的对象被称作是小对象,>32KB的是大对象。在小对象中,<=1024bytes的对象以8n bytes分配,1025<size<=32KB的对象以128n bytes大小分配,比如:要分配20bytes则返回的空闲块大小是24bytes的,这样在<=1024的情况下最多浪费7bytes,>1025则浪费127bytes。而大对象是以页大小4KB进行对齐的,最多会浪费4KB - 1 bytes。下图就是一个基本的free list的示意图:

实际上,一个free list(我称之为空闲块列表)就是一个数组索引多个链表,每个链表存放相同大小的块。可以根据要分配的内存大小size算出合适的块在free list中的下标,然后找到对应的空闲块链表。

tcmalloc的数据结构组织如下:

Thread-local free list:线程本地的空闲块cache,用于分配小对象。

Heap free list:中心free list,全局唯一,用于按页对齐分配大对象或者是将连续的多个页(被称作span)分割成多个小对象的空闲块分配给thread-local free list。

Page array:用于描述当前tcmalloc持有的内存状态,完成的是从page number到span的映射。

下面看一下小对象的分配:

(1)根据分配的size计算出对应的空闲块大小,从而确定对应空闲块链表,然后从thread local的free list进行分配。

(2)如果的空闲块链表非空,直接将头结点对应的空闲块返回并从空闲块链表中将其删除。

(3)如果空闲块链表是空的,需要从heap free list获取一个span。如果heap free list非空,则将span切分成多个相同大小的空闲块插入空闲块链表中,然后返回头结点。

(4)如果heap free list是空的,则调用sbrk或者mmap进行内存的分配一系列连续的内存页,作为span,然后切分成多个相同大小的空闲块插入空闲块链表,然后返回头结点。

大对象的分配就要简单多了,直接从heap free list分配4nKB大小的空闲块即可,如果heap free list不存在该大小的空闲块,通过系统调用分配连续的内存页。

tcmalloc还会对thread local cache进行垃圾收集,从而避免内存浪费。

二. 安装和使用

tcmalloc属于gperftools,安装比较简单,需要注意一下,在64bit系统上需要先安装libunwind(http://download.savannah.gnu.org/releases/libunwind/libunwind-0.99-beta.tar.gz,只能是这个版本),这个库为基于64位CPU和操作系统的程序提供了基本的堆栈辗转开解功能,其中包括用于输出堆栈跟踪的API、用于以编程方式辗转开解堆栈的API以及支持C++异常处理机制的API,32bit系统不需安装。在安装过程中,可能出现下列错误:

  1. gcc -DHAVE_CONFIG_H -I. -I../include -I../include -I../include/tdep-x86_64 -I. -D_GNU_SOURCE -DNDEBUG -g -O2 -fexceptions -Wall -Wsign-compare -MT setjmp/longjmp.lo -MD -MP -MF setjmp/.deps/longjmp.Tpo -c setjmp/longjmp.c -fPIC -DPIC -o setjmp/.libs/longjmp.o
  2. /usr/include/x86_64-linux-gnu/bits/setjmp2.h:26:13: error: 'longjmp' aliased to undefined symbol '_longjmp

是因为缺少编译选项U_FORTIFY_SOURCE,解决方法有两种:

1,尚未调用configure进行配置,则执行CPPFLAGS=-U_FORTIFY_SOURCE ./configure ... 会自动将编译选项添加到Makefile中。

2,已经配置过,直接修改Makefile,查找CPPFLAGS然后添加上-U_FORTIFY_SOURCE。

然后就是安装gperftools,这个正常安装即可,默认安装到/usr/local/lib下,完成后调用lddconfig添加到动态链接库缓存,然后就可以使用了。

使用方法,很简单,在编译时加上tcmalloc动态链接库即可

  1. g++ test.cpp -ltcmalloc

源码不需任何修改,tcmalloc会自动替换掉glibc默认的malloc和free,简简单单的一条命令就可以提升不少性能,very good。

TCMalloc小记【转】的更多相关文章

  1. TCMalloc小记

    周末抽空看了一下tcmalloc,了解了个大概.下面记录一下. 一. 原理 tcmalloc就是一个内存分配器,管理堆内存,主要影响malloc和free,用于降低频繁分配.释放内存造成的性能损耗,并 ...

  2. TCMalloc小记(转)

    一. 原理 tcmalloc就是一个内存分配器,管理堆内存,主要影响malloc和free,用于降低频繁分配.释放内存造成的性能损耗,并且有效地控制内存碎片.glibc中的内存分配器是ptmalloc ...

  3. [原]Paste.deploy 与 WSGI, keystone 小记

    Paste.deploy 与 WSGI, keystone 小记 名词解释: Paste.deploy 是一个WSGI工具包,用于更方便的管理WSGI应用, 可以通过配置文件,将WSGI应用加载起来. ...

  4. MySql 小记

    MySql  简单 小记 以备查看 1.sql概述 1.什么是sql? 2.sql发展过程? 3.sql标准与方言的关系? 4.常用数据库? 5.MySql数据库安装? 2.关键概念 表结构----- ...

  5. Linux-Memory小记

    以前我对这块认识很模糊,而且还有错误的认识:今天由我同事提醒,所以我决定来好好的缕缕这块的关系.图: -------------------------------------------1.参数含义 ...

  6. Git小记

    Git简~介 Git是一个分布式版本控制系统,其他的版本控制系统我只用过SVN,但用的时间不长.大家都知道,分布式的好处多多,而且分布式已经包含了集中式的几乎所有功能.Linus创造Git的传奇经历就 ...

  7. 广州PostgreSQL用户会技术交流会小记 2015-9-19

    广州PostgreSQL用户会技术交流会小记 2015-9-19 今天去了广州PostgreSQL用户会组织的技术交流会 分别有两个session 第一个讲师介绍了他公司使用PostgreSQL-X2 ...

  8. 东哥读书小记 之 《MacTalk人生元编程》

         一直以来的自我感觉:自己是个记性偏弱的人.反正从小读书就喜欢做笔记(可自己的字写得巨丑无比,尼玛不科学呀),抄书这事儿真的就常发生俺的身上. 因为那时经常要背诵课文之类,反正为了怕自己忘记, ...

  9. Paypal支付小记

    Paypal支付小记 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !impo ...

随机推荐

  1. Android四大基本组件介绍及生命周期

    Android四大基本组件分别是Activity,Service服务,Content Provider内容提供者,BroadcastReceiver广播接收器. 一.了解四大基本组件 Activity ...

  2. Memory loss【记忆缺失】

    Memory Loss Losing your ability to think and remember is pretty scary. We know the risk of dementia ...

  3. c++ vector实例

    #include <iostream> #include <string> #include <vector> #include <iostream> ...

  4. 笔记-python tutorial-9.classes

    笔记-python tutorial-9.classes 1.      Classes 1.1.    scopes and namespaces namespace: A namespace is ...

  5. 笔记-python-lib-re

    笔记-python-lib-re 1.      re模块简介 re模块提供了与perl类似的正则匹配功能. 要搜索的模式和字符串都可以是Unicode字符串(str)以及8位字符串(bytes).但 ...

  6. LOJ #6010. 「网络流 24 题」数字梯形

    #6010. 「网络流 24 题」数字梯形   题目描述 给定一个由 n nn 行数字组成的数字梯形如下图所示.梯形的第一行有 m mm 个数字.从梯形的顶部的 m mm 个数字开始,在每个数字处可以 ...

  7. 【Python】函数参数类型及用法

     一.函数的参数类型 def hs(a1,a2,a3,...): ****statements 其中a1,a2,a3是函数的参数,函数的参数类型可分为:必须参数.默认参数.可变参数(不定长参数).关键 ...

  8. Event log c++ sample.

    1. Init regedit. bool InitLog( TCHAR *logName, TCHAR *sourceName, TCHAR *MessageDllName ) { // This ...

  9. MongoDB快速入门学习笔记3 MongoDB的文档插入操作

    1.文档的数据存储格式为BSON,类似于JSON.MongoDB插入数据时会检验数据中是否有“_id”,如果没有会自动生成.shell操作有insert和save两种方法.当插入一条数据有“_id”值 ...

  10. 使用bat命令实现拖动快速安装APK包

    平时安装APK包,每次都要打命令adb install *********** 很繁琐,网上找到一个用BAT命令快速安装的方法   在桌面创建一个bat文件,输入: @echo off title i ...