tcc mallocc 测试为什么比自带的c mallocc 还慢

新手园地& & & 硬件问题Linux系统管理Linux网络问题Linux环境编程Linux桌面系统国产LinuxBSD& & & BSD文档中心AIX& & & 新手入门& & & AIX文档中心& & & 资源下载& & & Power高级应用& & & IBM存储AS400Solaris& & & Solaris文档中心HP-UX& & & HP文档中心SCO UNIX& & & SCO文档中心互操作专区IRIXTru64 UNIXMac OS X门户网站运维集群和高可用服务器应用监控和防护虚拟化技术架构设计行业应用和管理服务器及硬件技术& & & 服务器资源下载云计算& & & 云计算文档中心& & & 云计算业界& & & 云计算资源下载存储备份& & & 存储文档中心& & & 存储业界& & & 存储资源下载& & & Symantec技术交流区安全技术网络技术& & & 网络技术文档中心C/C++& & & GUI编程& & & Functional编程内核源码& & & 内核问题移动开发& & & 移动开发技术资料ShellPerlJava& & & Java文档中心PHP& & & php文档中心Python& & & Python文档中心RubyCPU与编译器嵌入式开发驱动开发Web开发VoIP开发技术MySQL& & & MySQL文档中心SybaseOraclePostgreSQLDB2Informix数据仓库与数据挖掘NoSQL技术IT业界新闻与评论IT职业生涯& & & 猎头招聘IT图书与评论& & & CU技术图书大系& & & Linux书友会二手交易下载共享Linux文档专区IT培训与认证& & & 培训交流& & & 认证培训清茶斋投资理财运动地带快乐数码摄影& & & 摄影器材& & & 摄影比赛专区IT爱车族旅游天下站务交流版主会议室博客SNS站务交流区CU活动专区& & & Power活动专区& & & 拍卖交流区频道交流区
富足长乐, 积分 5817, 距离下一级还需 2183 积分
论坛徽章:0
使用Tcmalloc的性能测试结果
今天研究了一下tcmalloc的使用,感觉效果惊人,很是激动,特此写出来以飨读者。关于tcmalloc的介绍,参考文章:TCMalloc:线程缓存的Malloc,是从google官方网站翻译出来的。
Tcmalloc的使用很简单,只需要-ltcmalloc_minimal即可。
测试代码:
#include &stdlib.h&
#include &stdio.h&
#include &unistd.h&
#include &time.h&
#include &sys/time.h&
#include &pthread.h&
#define MAX_COUNT
void fun(int i)
& && && &char* ptr = (char*)malloc(i);
& && && &free(ptr);
void* fun_thread(void*)
& && && &int i = 0;
& && && &int j = 1;
& && && &while(i++&MAX_COUNT)
& && && &{
& && && && && && & j ++;
& && && && && && & fun(j);
& && && && && && & if ( j&1024 )
& && && && && && && && && & j = 1;
& && && &}
#define MSECOND 1000000
int main()
& && && &struct timeval tpstart,
& && && &gettimeofday(&tpstart,NULL);
& && && &pthread_t _deliver_t;
& && && &pthread_create(&_deliver_t, NULL, fun_thread, NULL);
& && && &int i = 0;
& && && &int j = 1;
& && && &while(i++&MAX_COUNT)
& && && &{
& && && && && && & j ++;
& && && && && && & fun(i);
& && && && && && & if ( j & 1024 )
& && && && && && && && && & j = 1;
& && && && && && & //usleep(1);
& && && &}
& && && &gettimeofday(&tpend,NULL);
& && && &timeuse=MSECOND*(tpend.tv_sec-tpstart.tv_sec)+tpend.tv_usec-tpstart.tv_
& && && &timeuse/=MSECOND;
& && && &printf(&Used Time:%f\n&, timeuse);
& && && &return 0;
测试结果很是诱人:
[root@localhost test]# g++ 1.c -o 1 -lpthread
[root@localhost test]# ./1
Used Time:5.336594
[root@localhost test]# g++ 1.c -o 1 -lpthread -ltcmalloc_minimal
[root@localhost test]# ./1
Used Time:0.208050
提高了几十倍!当然测试的条件不是很完整,但是可以肯定tcmalloc效率提高了很多
[ 本帖最后由 rain_fish 于
22:23 编辑 ]
&&nbsp|&&nbsp&&nbsp|&&nbsp&&nbsp|&&nbsp&&nbsp|&&nbsp
家境小康, 积分 1877, 距离下一级还需 123 积分
论坛徽章:1
我觉得主要是由锁造成的
tcmalloc主要是为了多线程设计的
富足长乐, 积分 5817, 距离下一级还需 2183 积分
论坛徽章:0
不知道大家有没有用过tcmalloc的,tcmalloc中是不是也实现了内存池?
白手起家, 积分 0, 距离下一级还需 200 积分
论坛徽章:0
你这个分配了立即释放的实验意思不大。
应该是随机分配,随机释放才有意义。
论坛徽章:0
行了,要鼓励用通用的,标准的东西,哪天一换平台就傻眼了,不能跑了。
富足长乐, 积分 7242, 距离下一级还需 758 积分
论坛徽章:1
tcmalloc只需要链接上去就行了,他会替换掉libc的malloc
富足长乐, 积分 5264, 距离下一级还需 2736 积分
论坛徽章:0
,meanless test.
most of time, you could use some fix entry size mem_pool&&per threads to achive your goal.
巨富豪门, 积分 26497, 距离下一级还需 13503 积分
论坛徽章:13
哪里能下载到?
巨富豪门, 积分 26497, 距离下一级还需 13503 积分
论坛徽章:13
本帖最后由 yulihua49 于
13:22 编辑
使用Tcmalloc的性能测试结果
今天研究了一下tcmalloc的使用,感觉效果惊人,很是激动,特此写出来以飨读 ...
rain_fish 发表于
试了一下,X86-64:cc -static -o midsc midsc.o login.o transfer.o mod_sc.o scpool.o -L/home/qianwh/sdbc/lib&&-lsc -lscry -lstr -ljson -lpthread -L/usr/local/lib -ltcmalloc_minimal
/usr/local/lib/libtcmalloc_minimal.a(libtcmalloc_minimal_la-tcmalloc.o): In function `(anonymous namespace)::cpp_memalign(unsigned long, unsigned long)':
/home/qianwh/sdbc/google-perftools-1.5/src/tcmalloc.cc:1245: undefined reference to `std::set_new_handler(void (*)())'
/home/qianwh/sdbc/google-perftools-1.5/src/tcmalloc.cc:1246: undefined reference to `std::set_new_handler(void (*)())'
/home/qianwh/sdbc/google-perftools-1.5/src/tcmalloc.cc:1266: undefined reference to `__cxa_begin_catch'
/home/qianwh/sdbc/google-perftools-1.5/src/tcmalloc.cc:1266: undefined reference to `__cxa_end_catch'
/usr/local/lib/libtcmalloc_minimal.a(libtcmalloc_minimal_la-tcmalloc.o): In function `cpp_alloc':
/home/qianwh/sdbc/google-perftools-1.5/src/tcmalloc.cc:1197: undefined reference to `std::set_new_handler(void (*)())'
/home/qianwh/sdbc/google-perftools-1.5/src/tcmalloc.cc:1198: undefined reference to `std::set_new_handler(void (*)())'
.......
复制代码何故?
知道了。g++
巨富豪门, 积分 26497, 距离下一级还需 13503 积分
论坛徽章:13
使用Tcmalloc的性能测试结果
今天研究了一下tcmalloc的使用,感觉效果惊人,很是激动,特此写出来以飨读 ...
rain_fish 发表于
& & 在实际环境下测了一下。
线程池服务器,16核,20线程,总体性能提高大约30%。
北京盛拓优讯信息技术有限公司. 版权所有 京ICP备号 北京市公安局海淀分局网监中心备案编号:22
广播电视节目制作经营许可证(京) 字第1234号
中国互联网协会会员&&联系我们:
感谢所有关心和支持过ChinaUnix的朋友们
转载本站内容请注明原作者名及出处温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
阅读(2078)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
在LOFTER的更多文章
loftPermalink:'',
id:'fks_086075',
blogTitle:'chrome使用的开源工程介绍',
blogAbstract:'
在chrome地址栏输入',
blogTag:'',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:4,
publishTime:4,
permalink:'blog/static/',
commentCount:0,
mainCommentCount:0,
recommendCount:0,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:true,
hostIntro:'',
hmcon:'0',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}TCMalloc与Malloc对比
TCMalloc要比glibc
2.3的malloc(可以从一个叫作ptmalloc2的独立库获得)和其他我测试过的malloc都快。ptmalloc在一台2.8GHz的P4机器上(对于小对象)执行一次malloc及free大约需要300纳秒。而TCMalloc的版本同样的操作大约只需要50纳秒。malloc版本的速度是至关重要的,因为如果malloc不够快,应用程序的作者就很有可能在malloc之上写一个自己的。这就可能导致额外的代码复杂度,以及更多的内存占用――除非作者本身非常仔细地划分自由列表的大小并经常从自由列表中清除空闲的对象。
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还包含了一个以及一个。
如果你更想链接不包含堆测量器和检查器的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) 将他们分割成该尺寸类的一系列对象。(4)
像前面一样,将部分对象移入线程局部的自由列表中。
大对象的分配
一个大对象的尺寸(&
32K)会被除以一个页面尺寸(4K)并取整(大于结果的最小整数),同时是由中央页面堆来处理的。中央页面堆又是一个自由列表的阵列。对于i
256而言,第k个条目是一个由k个页面组成的自由列表。第256个条目则是一个包含了长度&=
256个页面的自由列表:
k个页面的一次分配通过在第k个自由列表中查找来完成。如果该自由列表为空,那么我们则在下一个自由列表中查找,如此继续。最终,如果必要的话,我们将在最后一个自由列表中查找。如果这个动作也失败了,我们将向系统获取内存(使用sbrk、mmap或者通过在/dev/mem中进行映射)。
如果k个页面的一次分配行为由连续的长度&
k的页面满足了,剩下的连续页面将被重新插回到页面堆的对应的自由列表中。
跨度(Span)
TCMalloc管理的堆由一系列页面组成。连续的页面由一个“跨度”(Span)对象来表示。一个跨度可以是已被分配或者是自由的。如果是自由的,跨度则会是一个页面堆链表中的一个条目。如果已被分配,它会是一个已经被传递给应用程序的大对象,或者是一个已经被分割成一系列小对象的一个页面。如果是被分割成小对象的,对象的尺寸类别会被记录在跨度中。
由页面号索引的中央数组可以用于找到某个页面所属的跨度。例如,下面的跨度a占据了2个页面,跨度b占据了1个页面,跨度c占据了5个页面最后跨度d占据了3个页面。
在一个32位的地址空间中,中央阵列由一个2层的基数树来表示,其中根包含了32个条目,每个叶包含了
215个条目(一个32为地址空间包含了 220个 4K
页面,所以这里树的第一层则是用25整除220个页面)。这就导致了中央阵列的初始内存使用需要128KB空间(215*4字节),看上去还是可以接受的。
在64位机器上,我们将使用一个3层的基数树。
当一个对象被解除分配时,我们先计算他的页面号并在中央阵列中查找对应的跨度对象。该跨度会告诉我们该对象是大是小,如果它是小对象的话尺寸类别是什么。如果是小对象的话,我们将其插入到当前线程的线程缓存中对应的自由列表中。如果线程缓存现在超过了某个预定的大小(默认为2MB),我们便运行垃圾收集器将未使用的对象从线程缓存中移入中央自由列表。
如果该对象是大对象的话,跨度会告诉我们该对象覆盖的页面的范围。假设该范围是[p,q]。我们还会查找页面p-1和页面q+1对应的跨度。如果这两个相邻的跨度中有任何一个是自由的,我们将他们和[p,q]的跨度接合起来。最后跨度会被插入到页面堆中合适的自由列表中。
小对象的中央自由列表
就像前面提过的一样,我们为每一个尺寸类别设置了一个中央自由列表。每个中央自由列表由两层数据结构来组成:一系列跨度和每个跨度一个自由对象的链表。
通过从某个跨度中移除第一个条目来从中央自由列表分配一个对象。(如果所有的跨度里只有空链表,那么首先从中央页面堆中分配一个尺寸合适的跨度。)
一个对象可以通过将其添加到他包含的跨度的链表中来返回到中央自由列表中。如果链表长度现在等于跨度中所有小对象的数量,那么该跨度就是完全自由的了,就会被返回到页面堆中。
线程缓存的垃圾收集
某个线程缓存当缓存中所有对象的总共大小超过2MB的时候,会对他进行垃圾收集。垃圾收集阈值会自动根据线程数量的增加而减少,这样就不会因为程序有大量线程而过度浪费内存。
我们会遍历缓存中所有的自由列表并且将一定数量的对象从自由列表移到对于得中央列表中。
从某个自由列表中移除的对象的数量是通过使用一个每列表的低水位线L来确定的。L记录了自上一次垃圾收集以来列表最短的长度。注意,在上一次的垃圾收集中我们可能只是将列表缩短了L个对象而没有对中央列表进行任何额外访问。我们利用这个过去的历史作为对未来访问的预测器并将L/2个对象从线程缓存自由列表中移到相应的中央自由列表中。这个算法有个很好的特性是,如果某个线程不再使用某个特定的尺寸时,该尺寸的所有对象都会很快从线程缓存被移到中央自由列表,然后可以被其他缓存利用。
PTMalloc2单元测试
PTMalloc2包(现在已经是glibc的一部分了)包含了一个单元测试程序t-test1.c。它会产生一定数量的线程并在每个线程中进行一系列分配和解除分配;线程之间没有任何通信除了在内存分配器中同步。
t-test1(放在tests/tcmalloc/中,编译为ptmalloc_unittest1)用一系列不同的线程数量(1~20)和最大分配尺寸(64B~32KB)运行。这些测试运行在一个2.4GHz
双核心Xeon的RedHat 9系统上,并启用了超线程技术, 使用了Linux
glibc-2.3.2,每个测试中进行一百万次操作。在每个案例中,一次正常运行,一次使用LD_PRELOAD=libtcmalloc.so。
下面的图像显示了TCMalloc对比PTMalloc2在不同的衡量指标下的性能。首先,现实每秒全部操作(百万)以及最大分配尺寸,针对不同数量的线程。用来生产这些图像的原始数据(time工具的输出)可以在t-test1.times.txt中找到。
TCMalloc要比PTMalloc2更具有一致地伸缩性——对于所有线程数量&1的测试,小分配达到了约7~9百万操作每秒,大分配降到了约2百万操作每秒。单线程的案例则明显是要被剔除的,因为他只能保持单个处理器繁忙因此只能获得较少的每秒操作数。PTMalloc2在每秒操作数上有更高的方差——某些地方峰值可以在小分配上达到4百万操作每秒,而在大分配上降到了&1百万操作每秒。
TCMalloc在绝大多数情况下要比PTMalloc2快,并且特别是小分配上。线程间的争用在TCMalloc中问题不大。
TCMalloc的性能随着分配尺寸的增加而降低。这是因为每线程缓存当它达到了阈值(默认是2MB)的时候会被垃圾收集。对于更大的分配尺寸,在垃圾收集之前只能在缓存中存储更少的对象。
TCMalloc性能在约32K最大分配尺寸附件有一个明显的下降。这是因为在每线程缓存中的32K对象的最大尺寸;对于大于这个值得对象TCMalloc会从中央页面堆中进行分配。
下面,CPU时间的每秒操作数(百万)以及线程数量的图像,最大分配尺寸64B~128KB。
这次我们再一次看到TCMalloc要比PTMalloc2更连续也更高效。对于&32K的最大分配尺寸,TCMalloc在大线程数的情况下典型地达到了CPU时间每秒约0.5~1百万操作,同时PTMalloc通常达到了CPU时间每秒约0.5~1百万,还有很多情况下要比这个数字小很多。在32K最大分配尺寸之上,TCMalloc下降到了每CPU时间秒1~1.5百万操作,同时PTMalloc对于大线程数降到几乎只有零(也就是,使用PTMalloc,在高度多线程的情况下,很多CPU时间被浪费在轮流等待锁定上了)。
对于某些系统,TCMalloc可能无法与没有链接libpthread.so(或者你的系统上同等的东西)的应用程序正常工作。它应该能正常工作于使用glibc
2.3的Linux上,但是其他OS/libc的组合方式尚未经过任何测试。
TCMalloc可能要比其他malloc版本在某种程度上更吃内存,(但是倾向于不会有其他malloc版本中可能出现的爆发性增长。)尤其是在启动时TCMalloc会分配大约240KB的内部内存。
不要试图将TCMalloc载入到一个运行中的二进制程序中(例如,在Java中使用JNI)。二进制程序已经使用系统malloc分配了一些对象,并会尝试将它们传递到TCMalloc进行解除分配。TCMalloc是无法处理这种对象的。
转载: 文章地址
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。博客分类:
  TCMalloc(Thread-Caching Malloc)是google开发的开源工具──“”中的成员。与标准的glibc库的malloc相比,TCMalloc在内存的分配上效率和速度要高得多,可以在很大程度上提高MySQL服务器在高并发情况下的性能,降低系统负载。  TCMalloc的实现原理和测试报告请见一篇文章:《》  为MySQL添加TCMalloc库的安装步骤(Linux环境):  1、64位操作系统请先安装libunwind库,32位操作系统不要安装。libunwind库为基于64位CPU和操作系统的程序提供了基本的堆栈辗转开解功能,其中包括用于输出堆栈跟踪的API、用于以编程方式辗转开解堆栈的API以及支持C++异常处理机制的API。
tar zxvf libunwind-0.99-alpha.tar.gz
cd libunwind-0.99-alpha/
CFLAGS=-fPIC ./configure
make CFLAGS=-fPIC
make CFLAGS=-fPIC install
  2、安装google-perftools:
tar zxvf google-perftools-0.97.tar.gz
cd google-perftools-0.97/
./configure
make && make install
echo "/usr/local/lib" & /etc/ld.so.conf.d/usr_local_lib.conf
/sbin/ldconfig
  3、修改MySQL启动脚本(根据你的MySQL安装位置而定):
/usr/local/mysql/bin/mysqld_safe
  在# executing mysqld_safe的下一行,加上:
LD_PRELOAD=/usr/local/lib/libtcmalloc.so
  保存后退出,然后重启MySQL服务器。  4、使用lsof命令查看tcmalloc是否起效:
/usr/sbin/lsof
-n | grep tcmalloc
  如果发现以下信息,说明tcmalloc已经起效:  mysqld
/usr/local/lib/libtcmalloc.so.0.0.0
  注:2008年6月2日,修正了libunwind在x86_64位操作系统下的编译错误,TCMalloc无法加载等问题。  涉及修改内容:  1、libunwind的编译参数改为:  CFLAGS=-fPIC ./configure  make CFLAGS=-fPIC  make CFLAGS=-fPIC install  2、增加:  echo "/usr/local/lib" &
/etc/ld.so.conf.d/usr_local_lib.conf  /sbin/ldconfig  3、修改MySQL加载TCMalloc的语句:  export LD_PRELOAD=/usr/local/lib/libtcmalloc.so  感谢网友router。
09:53 | by 张宴 ]
  [文章作者:张宴 本文版本:v1.1 最后修改: 转载请注明出自:]
  TCMalloc(Thread-Caching Malloc)是google开发的开源工具──“google-perftools”中的成员。与标准的glibc库的malloc相比,TCMalloc在内存的分配上效率和速度要高得多,可以在很大程度上提高MySQL服务器在高并发情况下的性能,降低系统负载。
  TCMalloc的实现原理和测试报告请见一篇文章:《TCMalloc:线程缓存的Malloc》
  为MySQL添加TCMalloc库的安装步骤(Linux环境):
  1、64位操作系统请先安装libunwind库,32位操作系统不要安装。libunwind库为基于64位CPU和操作系统的程序提供了基本的堆栈辗转开解功能,其中包括用于输出堆栈跟踪的API、用于以编程方式辗转开解堆栈的API以及支持C++异常处理机制的API。
http://download.savannah.gnu.org/releases/libunwind/libunwind-0.99-alpha.tar.gz
zxvf libunwind-0.99-alpha.tar.gz
libunwind-0.99-alpha/
CFLAGS=-fPIC
./configure
CFLAGS=-fPIC
CFLAGS=-fPIC install
  2、安装google-perftools:
http://google-/files/google-perftools-0.97.tar.gz
zxvf google-perftools-0.97.tar.gz
google-perftools-0.97/
./configure
&& make install
"/usr/local/lib" & /etc/ld.so.conf.d/usr_local_lib.conf
/sbin/ldconfig
  3、修改MySQL启动脚本(根据你的MySQL安装位置而定):
/usr/local/mysql/bin/mysqld_safe
  在# executing mysqld_safe的下一行,加上:
LD_PRELOAD=/usr/local/lib/libtcmalloc.so
  保存后退出,然后重启MySQL服务器。
  4、使用lsof命令查看tcmalloc是否起效:
/usr/sbin/lsof
-n | grep tcmalloc
  如果发现以下信息,说明tcmalloc已经起效:
  mysqld
/usr/local/lib/libtcmalloc.so.0.0.0
  注:2008年6月2日,修正了libunwind在x86_64位操作系统下的编译错误,TCMalloc无法加载等问题。
  涉及修改内容:
  1、libunwind的编译参数改为:
  CFLAGS=-fPIC ./configure
  make CFLAGS=-fPIC
  make CFLAGS=-fPIC install
  2、增加:
  echo "/usr/local/lib" &
/etc/ld.so.conf.d/usr_local_lib.conf
  /sbin/ldconfig
  3、修改MySQL加载TCMalloc的语句:
  export LD_PRELOAD=/usr/local/lib/libtcmalloc.so
  感谢网友router。
linux , mysql , google , tcmalloc
技术大类 >> 数据库技术 | 评论(33) | 引用(0) | 阅读(27579)
报错啊,老大,怎么办?
unrecognized option `-static-libcxa'
/usr/bin/ld:
dwarf/.libs/Lfind_proc_info-lsb.o: relocation R_X86_64_PC32 against
`_ULx86_64_dwarf_search_unwind_table' can not be used when making a shared
recompile with -fPIC
/usr/bin/ld:
final link failed: Bad value
ld returned 1 exit status
*** [libunwind.la] Error 1
Leaving directory `/usr/local/src/libunwind-0.99-alpha/src'
*** [all] Error 2
Leaving directory `/usr/local/src/libunwind-0.99-alpha/src'
*** [all-recursive] Error 1
张宴 回复于
32位操作系统不要安装libunwind库,直接安装google-perftools即可。
我是64位系统啊
解决了64位libunwind编译不成功的问题
CFLAGS=-fPIC
./configure
CFLAGS=-fPIC
CFLAGS=-fPIC install
加入export LD_PRELOAD =
"/usr/local/lib/libtcmalloc.so" 后启动mysql
/usr/local/webserver/mysql/bin/mysqld_safe
--defaults-file=/usr/local/webserver/f &
/usr/local/webserver/mysql/bin/mysqld_safe:
line 12: export: `=': not a valid identifier
/usr/local/webserver/mysql/bin/mysqld_safe:
line 12: export: `/usr/local/lib/libtcmalloc.so': not a valid identifier
mysqld daemon with databases from /usr/local/webserver/mysql/data
将export LD_PRELOAD = "/usr/local/lib/libtcmalloc.so"更改为LD_PRELOAD =
"/usr/local/lib/libtcmalloc.so"
LD_PRELOAD:
command not found
mysql版本为5.0.22
老大帮忙解决下啊
把启动的问题解决了,如下:
# 修改 mysql 啟動, 讓他使用 TCMalloc
# 修改 第 387 行, 於此行最前面加入
LD_PRELOAD="/usr/lib/libtcmalloc.so"(在 mysql 啟動前先載入環境變數(mysql 啟動的 script 就是 /usr/bin/mysqld_safe), 讓 tcmalloc = glibc 的 malloc(), 於最前面加入環境變數即可)
行就是 mysql start 的那行命令, 此行修改完成如下:
LD_PRELOAD="/usr/lib/libtcmalloc.so" $NOHUP_NICENESS
$ledir/$MYSQLD $defaults --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR
$USER_OPTION --pid-file
=$pid_file
--skip-external-locking 2&&1 | $ERR_LOGGER -t mysqld & wait
但新问题又来了
使用lsof命令查看tcmalloc是否起效:
/usr/sbin/lsof
-n | grep tcmalloc
没有发现tcmalloc
哎,忙活了一晚上,还是不行
试着编译mysql
./configure
--prefix=/usr/local/webserver/mysql/ --without-debug
--with-unix-socket-path=/tmp/mysql.sock --with-client-ldflags=-all-static
--with-mysqld-ldflags="-all-static -ltcmalloc" --enable-assembler
--with-extra-charsets=gbk,gb2312,utf8 --with-pthread --enable-thread-safe-client
/lib/libtcmalloc.a(stacktrace.o)(.text+0xdf):
In function `GetStackTrace(void**, int, int)':
src/stacktrace_libunwind-inl.h:65:
undefined reference to `_ULx86_64_init_local'
/usr/local/lib/libtcmalloc.a(stacktrace.o)(.text+0x103):src/stacktrace_libunwind-inl.h:70:
undefined reference to `_ULx86_64_get_reg'
/usr/local/lib/libtcmalloc.a(stacktrace.o)(.text+0x115):src/stacktrace_libunwind-inl.h:78:
undefined reference to `_ULx86_64_step'
/usr/local/lib/libtcmalloc.a(stacktrace.o)(.text+0x28f):
In function `GetStackFrames(void**, int*, int, int)':
src/stacktrace_libunwind-inl.h:126:
undefined reference to `_ULx86_64_init_local'
/usr/local/lib/libtcmalloc.a(stacktrace.o)(.text+0x2a4):src/stacktrace_libunwind-inl.h:130:
undefined reference to `_ULx86_64_step'
/usr/local/lib/libtcmalloc.a(stacktrace.o)(.text+0x2be):src/stacktrace_libunwind-inl.h:130:
undefined reference to `_ULx86_64_get_reg'
/usr/local/lib/libtcmalloc.a(stacktrace.o)(.text+0x2e8):src/stacktrace_libunwind-inl.h:137:
undefined reference to `_ULx86_64_get_reg'
/usr/local/lib/libtcmalloc.a(stacktrace.o)(.text+0x2f4):src/stacktrace_libunwind-inl.h:139:
undefined reference to `_ULx86_64_step'
/usr/local/lib/libtcmalloc.a(stacktrace.o)(.text+0x30e):src/stacktrace_libunwind-inl.h:139:
undefined reference to `_ULx86_64_get_reg'
重新写参数
CFLAGS=-fPIC
LDFLAGS="-lunwind -lunwind-ULx86_64" ./configure........
LDFLAGS="-lunwind -lunwind-ULx86_64" CFLAGS=-fPIC
/usr/bin/ld:
cannot find -lunwind-ULx86_64
-s /usr/local/lib/libunwind-x86_64.so.7.0.0
/usr/local/lib/libunwind-ULx86_64.so
还是提示/usr/bin/ld: cannot find -lunwind-ULx86_64
估计是google这个工具CPU参数是x86_64而我服务器参数是ULx86_64造成的这个bug
崩溃了!老大救命啊!
张宴 回复于
启动MySQL之前:
"/usr/local/lib" & /etc/ld.so.conf.d/usr_local_lib.conf
/sbin/ldconfig
本文已修正。
老大,mysql采用的静态编译with-mysqld-ldflags=-all-static
是不是不能使用外挂方式哦?
LD_PRELOAD=/usr/local/lib/libtcmalloc.so
能否告知我您的gtalk QQ 或者msn等联系方式,我想请教下,我的email gtalk :
应该是采用了with-mysqld-ldflags=-all-static 就不行!我也遇到同样问题!
请问张老师,我本来想用编译到mysql的方式使用TCMalloc,但无法编译成功mysql,报错undefined reference to
`_ULx86_64_init_local'
然后我在make加上参数make LDFLAGS="-lunwind -lunwind-ULx86_64"
CFLAGS=-fPIC
报错/usr/bin/ld: cannot find -lunwind-ULx86_64,lib里面没有unwind-ULx86_64.so类似的文件,只有unwind-x86_64,我打算放弃编译,采用外挂的方式使用TCMalloc,但以前的mysql采用的with-mysqld-ldflags=-all-static
方式编译,不支持外挂,请问应该怎么重新编译mysql才能支持外挂
编译不成功
但外挂搞好了
7646979 /usr/local/lib/libtcmalloc.so.0.0.0
7646979 /usr/local/lib/libtcmalloc.so.0.0.0
7646979 /usr/local/lib/libtcmalloc.so.0.0.0
7646979 /usr/local/lib/libtcmalloc.so.0.0.0
7646979 /usr/local/lib/libtcmalloc.so.0.0.0
具体步骤和张老师的一模一样,只是重新编译了mysql
取消掉静态链接。
终于也安装成功了,和 router 说的一样,
需要重新编译一次MYSQL,
configure时要去掉这一个参数
with-mysqld-ldflags=-all-static
我的环境:CentOS 4.6 32bit,不需要安装libunwind库。
有没有不需要重新编译的办法,对于运营系统不能随便动啊!
有没有不需要重新编译MYSQL的办法呢?因为运营系统哪能随便重新编译程序呢?
张宴 回复于
原有MySQL不停止,重新编译MySQL,到make && make
install完成,不会影响到原有服务。重启MySQL,新编译的配置生效。
为安全起见,你也可以将新的MySQL程序编译安装到不同的路径,启动时数据库文件存放路径指定以前的位置即可。
请教博主帮忙!
我完全按上面写的操作修改后重启了也没发现启用这个库,我的mysql是用官方提供的RPM包安装的,可能也是全静态编译了的版本。
我按照张兄的方法重新编译了也没有看到那个tcmalloc!不知道什么原因!
在MYSQL下载的不用安装的源码不知道是否可以? 还有rpm包如何解决呢?
--with-mysqld-ldflags="-all-static
-ltcmalloc -lstacktrace"
这个是否可以启用 tcmalloc 呢,lsof 里面没有发现,难道静态编译不进去吗?
--with-mysqld-ldflags="-all-static
-ltcmalloc -lstacktrace"
-lstacktrace
参数添加后会报错,说找不到stacktrace,但去掉这个-lstacktrace参数重新编译是可以成功的,但在执行下面的命令时:
[root@Chinarenservice
oracle]# lsof -n | grep tcmalloc
[root@Chinarenservice
什么也没有发现!说明不成功!
tcmalloc,我已经装上了,lsof也能看到
请问张老师,mysql使用该插件和不使用该插件,您有性能测试数据对比么?
浏览: 16102 次
来自: 广州
u12下/etc/init/mysql启动脚本好像不是调用my ...
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'}

我要回帖

更多关于 malloc和new的区别 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信