Redis源码分析-TCMalloc
redis很多地方都在调用zmalloc函数
zmalloc在这里定义zmalloc.c
void *zmalloc(size_t size) {void *ptr = malloc(size+PREFIX_SIZE);if (!ptr) zmalloc_oom_handler(size);
#ifdef HAVE_MALLOC_SIZEupdate_zmalloc_stat_alloc(zmalloc_size(ptr));return ptr;
#else*((size_t*)ptr) = size;update_zmalloc_stat_alloc(size+PREFIX_SIZE);return (char*)ptr+PREFIX_SIZE;
#endif
}
malloc的定义
/* Explicitly override malloc/free etc when using tcmalloc. */
#if defined(USE_TCMALLOC)
#define malloc(size) tc_malloc(size)
#define calloc(count,size) tc_calloc(count,size)
#define realloc(ptr,size) tc_realloc(ptr,size)
#define free(ptr) tc_free(ptr)
#elif defined(USE_JEMALLOC)
#define malloc(size) je_malloc(size)
#define calloc(count,size) je_calloc(count,size)
#define realloc(ptr,size) je_realloc(ptr,size)
#define free(ptr) je_free(ptr)
#endif
编译时的src目录下的makefile文件中的选项:
ifeq ($(MALLOC),tcmalloc)FINAL_CFLAGS+= -DUSE_TCMALLOCFINAL_LIBS+= -ltcmalloc
endififeq ($(MALLOC),tcmalloc_minimal)FINAL_CFLAGS+= -DUSE_TCMALLOCFINAL_LIBS+= -ltcmalloc_minimal
endififeq ($(MALLOC),jemalloc)DEPENDENCY_TARGETS+= jemallocFINAL_CFLAGS+= -DUSE_JEMALLOC -I../deps/jemalloc/includeFINAL_LIBS+= ../deps/jemalloc/lib/libjemalloc.a -ldl
endif
将tcmalloc通过“-ltcmalloc”链接器标志接入模块
Tcmalloc概述
tcmalloc将内存请求分为两类,大对象请求和小对象请求,大对象为>=32K的对象。|
tcmalloc会为每个线程分配线程局部缓冲
对于小对象请求,可以直接从线程局部缓冲区获取,如果线程局部缓冲区没有空闲内存,则从central heap中一次性获取一连串小对象。
tcmalloc对于小内存,按8的整数次倍分配,对于大内存,按4K的整数次倍分配。
这样做有两个好处,一是分配的时候比较快。二是短期的收益比较大,分配的小内存至多浪费7个字节,大内存则4K
当某个线程缓存当缓存中所有对象的总共大小超过2MB的时候,会对他进行垃圾收集。垃圾收集阈值会自动根据线程数量的增加而减少,这样就不会因为程序有大量线程而过度浪费内存。
内存泄露检测
使用Tcmalloc的程序,用valgrind无法检测内存泄露,可以使用google-perftools提供的heap checker
使用方法:
export HEAPCHECK=TYPE
TYPE可以为:minimal、normal、strict、draconian
http://code.google.com/p/gperftools/downloads/list
Tcmalloc通过preload或者直接动态链接的方式对malloc等内存分配和释放函数进行截获并提供服务。Tcmalloc提供接口主要涵盖malloc.h的接口
使用
要使用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字节。
大对象的分配
一个大对象的尺寸(> 32K)会被除以一个页面尺寸(4K)并取整(大于结果的最小整数),同时是由中央页面堆来处理的。中央页面堆又是一个自由列表的阵列。对于i < 256而言,第k个条目是一个由k个页面组成的自由列表。
跨度(Span)
TCMalloc管理的堆由一系列页面组成。连续的页面由一个“跨度”(Span)对象来表示。一个跨度可以是已被分配或者是自由的。如果是自由的,跨度则会是一个页面堆链表中的一个条目。如果已被分配,它会是一个已经被传递给应用程序的大对象,或者是一个已经被分割成一系列小对象的一个页面。如果是被分割成小对象的,对象的尺寸类别会被记录在跨度中。
解除分配
当一个对象被解除分配时,我们先计算他的页面号并在中央阵列中查找对应的跨度对象。该跨度会告诉我们该对象是大是小,如果它是小对象的话尺寸类别是什么。如果是小对象的话,我们将其插入到当前线程的线程缓存中对应的自由列表中。如果线程缓存现在超过了某个预定的大小(默认为2MB),我们便运行垃圾收集器将未使用的对象从线程缓存中移入中央自由列表。
如果该对象是大对象的话,跨度会告诉我们该对象覆盖的页面的范围。假设该范围是[p,q]。我们还会查找页面p-1和页面q+1对应的跨度。如果这两个相邻的跨度中有任何一个是自由的,我们将他们和[p,q]的跨度接合起来。最后跨度会被插入到页面堆中合适的自由列表中。
小对象的中央自由列表
就像前面提过的一样,我们为每一个尺寸类别设置了一个中央自由列表。每个中央自由列表由两层数据结构来组成:一系列跨度和每个跨度一个自由对象的链表。
线程缓存的垃圾收集
某个线程缓存当缓存中所有对象的总共大小超过2MB的时候,会对他进行垃圾收集。垃圾收集阈值会自动根据线程数量的增加而减少,这样就不会因为程序有大量线程而过度浪费内存。
我们会遍历缓存中所有的自由列表并且将一定数量的对象从自由列表移到对于得中央列表中。
注意:
TCMalloc可能要比其他malloc版本在某种程度上更吃内存,(但是倾向于不会有其他malloc版本中可能出现的爆发性增长。)尤其是在启动时TCMalloc会分配大约240KB的内部内存。
不要试图将TCMalloc载入到一个运行中的二进制程序中(例如,在Java中使用JNI)。二进制程序已经使用系统malloc分配了一些对象,并会尝试将它们传递到TCMalloc进行解除分配。TCMalloc是无法处理这种对象的。
翻译参考:http://blog.163.com/cp7618@yeah/blog/static/70234777201251345350339/
原文地址:http://google-perftools.googlecode.com/svn/trunk/doc/tcmalloc.html
更多参考:glibc内存泄露以及TCmalloc 简单分析
使用Google的开源TCMalloc库,提高MySQL在高并发情况下的性能[张宴原创]
TCMalloc:线程缓存的Malloc
深入Linux的内存管理,关于PTMalloc3、Hoard和TCMalloc
在应用程序中替换Linux中Glibc的malloc的四种方法
Google performance Tools (gperftools) 使用心得
相关文章:
让AI训练AI,阿里和浙大的“AI训练师助手”是这样炼成的
不久前,人力资源社会保障部发布了一种炙手可热的新职业:AI训练师。没想到,浙江大学与阿里安全的人工智能训练师马上创造出一个 “AI训练师助手”,高效打造AI深度模型,应对海量应用场景的增加,让AI训练模型面…

用 Navicat for Oracle 管理 Oracle10g/11g 数据库
Navicat for xxx 是一个优秀的数据库管理客户端,有 MySQL、Oracle 等版本。建议大家最好用 Enterprise 版本,功能全面一些,但较之于免费的 Lite 版,企业版可是要花银子买的。 安装 Navicat for Oracle 后,首先需要建一…

借一个同事的经历,谈一谈程序员的成长
一个很久之前的同事,今天找我,想让我帮他推荐下,去我们公司来工作,因为认识很久,就和他说了说公司的现状,也询问了一下他的状况,寒暄几句,让他下周等面试。 这位同事是之前一起做游戏…

select,epoll,poll比较
select,poll,epoll简介 select select本质上是通过设置或者检查存放fd标志位的数据结构来进行下一步处理。这样所带来的缺点是: 1 单个进程可监视的fd数量被限制 2 需要维护一个用来存放大量fd的数据结构,这样会使得用户空间和内…
华为开发者大会HDC.Cloud技术探秘:云搜索服务技术实践
搜索是一个古老的技术,从互联网发展的第一天开始,搜索技术就绽放出了惊人的社会和经济价值。随着信息社会快速发展,数据呈爆炸式增长,搜索技术通过数据收集与处理,满足信息共享与快速检索的需求。基于搜索技术…

从今天开始,自己做SEO。
1.购买了一点黑链。开始优化之路。 2.更改了关键词,描述。 3.整理了友情链接。 4.购买了VPS服务器:点击查看 转载于:https://www.cnblogs.com/zq535228/archive/2010/06/09/1754986.html

Elasticsearch2.2.0配置文件说明
为什么80%的码农都做不了架构师?>>> 官方配置文档 https://www.elastic.co/guide/en/elasticsearch/reference/current/setup.html 配置详解 # ---------------------------------- Cluster (集群配置)----------------------…

各种类型的字节数
int类型比较特殊,具体的字节数同机器字长和编译器有关。如果要保证移植性,尽量用__int16 __int32 __int64吧,或者自己typedef int INT32一下。 C、C标准中只规定了某种类型的最小字节数(防止溢出) 64位指的是cpu通用寄…
154 万 AI 开发者用数据告诉你,中国 AI 如何才能弯道超车?| 中国 AI 应用开发者报告...
曾经,软件吞噬世界。现在,AI 吞噬软件。作者 | 屠敏数据 | 杨阳、刘学涛可视化&策划 | 唐小引出品 | CSDN(ID:CSDNnews)从三年前年薪 25 万只是白菜价,到去年华为以年薪最高达 201 万招揽顶尖应届毕业生…

中国移动用户能不能用WCDMA网?(世界杯与通信2)
到南非有移动的用户也有联通的用户,联通的网络快这是肯定的,不过联通的通话价格也比移动的高,就有人希望拿着移动的号去南非,最好也能享受WCDMA的网络速度,这样就是两全其美了,对于这个问题,在国…

平安陆金所-点金计划,简直是骗子行为。
陆金所点金计划,让人防不胜防。平安保险,骗子中的教练。 转载于:https://www.cnblogs.com/hthf/p/5205921.html
深度分析define预处理指令
#define语句 预处理 宏替换 --以上出自《C语言入门经典(第四版)》 #和## --出自《C语言程序设计:现代方法(第2版)》 #undef取消定义 --以上出自《21天学通C语言(第6版)》

建立YUM服务器CENTOS
1 ,YUM Client:要保证安装有如下软件包:yum-3.2.19-18.el5.centosyum-metadata-parser-1.1.2-2.el52 ,YUM Server:要保证安装有如下软件包:yum-3.2.19-18.el5.centosyum-metadata-parser-1.1.2-2.el5yum-fastestmirror…
数据库设计的10个最佳实践
作者 | Emily Williamson译者 | 孙薇,责编 | 屠敏出品 | CSDN(ID:CSDNnews)以下为译文:数据库是应用及计算机的核心元素,负责存储运行软件应用所需的一切重要数据。为了保障应用正常运行,总有一…

十进制转化为十六进制分割高低位
2019独角兽企业重金招聘Python工程师标准>>> 将十进制1000,转化为十六进制,则为0x03E8,如果得到高低位,high0x03,low0xE8 BYTE high;BYTE low;int temp_data1nWeightValue;highBYTE(temp_data1 >>8);int temp_data2nWeightV…
Nginx内存池--pool代码抽取(链表套路)
ngx_palloc.c文件 ngx_palloc_large_hm是自己写的代码没有nginx原版的ngx_palloc_large写的好,细节要品味才会发现nginx的美 nginx链表的套路,正好是两种插入“从前插”和“从后插”,有些许差别 #include <stdio.h> #include <std…

阿里再次主办大数据世界杯, KDD Cup2020正式开赛
记者从国际计算机科学顶会ACM SIGKDD官网获悉,KDD Cup 2020今日正式开赛,本届比赛由阿里巴巴达摩院主办。随即,阿里公布了认知智能、曝光偏差两大赛题方向,并向全球参赛者开放最大规模的商品多模态数据集。阿里也是两次举办该赛事…

grep 正则表达式
grep 正则表达式来源:http://blog.rednet.cn/user1/213546/archives/2007/35795.html以下为整理的grep 正则表达式的大部分功能,详细参见man grep: 要用好grep这个工具,其实就是要写好正则表达式,所以这里不对grep的所有功能进行实例讲解,只列…

Mybatis缓存机制理解及配置
2019独角兽企业重金招聘Python工程师标准>>> 1. Ehcache EHCache是来自sourceforge(http://ehcache.sourceforge.net/)的开源项目,也是纯Java实现的简单、快速的Cache组件。EHCache支持内存和磁盘的缓存,支持LRU、…

浅谈无缓存I/O操作和标准I/O文件操作区别 (转载)
首先,先稍微了解系统调用的概念: 系统调用,英文名system call,每个操作系统都在内核里有一些内建的函数库,这些函数可以用来完成一些系统系统调用把应用程序的请求传给内核,调用相应的的内核函数完成所需的…

Android之ListActivity(一):布局与数据绑定
Android中的列表,当然也可以用ListView来完成所需要的功能,用法是一样的。 废话不说,来关键的。 LiveActivity本身继承了关于List操作的众多接口,我们可以方便的重写这些操作中需要的方法来实现自己需要的功能。 如果要用ListActi…
用于单图像超分辨率的对偶回归网络,达到最新SOTA | CVPR 2020
作者 | Yong Guo, Jian Chen等译者 | 刘畅出品 | AI科技大本营(ID:rgznai100)通过学习从低分辨率(LR)图像到高分辨率(HR)图像之间的非线性映射函数,深度神经网络在图像超分辨率(SR&a…

老生常谈,joomla wordpress drupal,你该选择哪个CMS?
本人从事Joomla建站多年,给客户建站都是用Joomla,所以我会极力推荐你选择Joomla? No No No,这样未免太Hard sale了。 虽然这是一个会经常被提到的问题,网上也有不少优秀的答案,但我还是想把自己的想法跟大家…
利用TCMalloc替换Nginx和Redis默认glibc库的malloc内存分配
TCMalloc的全称为Thread-Caching Malloc,是谷歌开发的开源工具google-perftools中的一个成员。与标准的glibc库的Malloc相比,TCMalloc库在内存分配效率和速度上要高很多,这在很大程度上提高了服务器在高并发情况下的性能,从而降低…

Silverlight Analytics Framework(开源分析框架)
Silverlight Analytics Framework是由微软官方推出的WPF/Silverlight扩展Web分析框架.该框架与10余家第三方分析服务结合,使应用可以跟踪程序如何使用的详细情况,为用户提供诸如可用性和视频质量等细节分析。用户可以了解到这些应用软件的使用细节&#…
Python炫技操作:条件语句的七种写法
作者 | 写代码的明哥来源 | Python编程时光有的人说 Python 入门容易,但是精通难的语言,这点我非常赞同。Python 语言里有许多(而且是越来越多)的高级特性,是 Python 发烧友们非常喜欢的。在这些人的眼里,能…

puppet(1.7-2.1)
puppet配置模块(一)模块是puppet的最大单元,模块里面有类,类下面有资源。同步文件、远程执行命令、cron等叫做资源,都是通过模块来实现的。下面我们来定义一个模块:在服务端上做如下操作:mkdir /etc/puppet/modules/te…

ldconfig动态链接库管理以及修改ld.so.conf.d
将"/usr/local/lib"加入配置文件重 执行命令: #echo "/usr/local/lib" >> /etc/ld.so.conf 然后再直接执行: #ldconfig /etc/ld.so.conf.d/* 或/etc/ld.so.conf和ldconfig. /etc/ld.so.conf.d/*目录下的文件和/etc/ld.so.co…
深度残差收缩网络:借助注意力机制实现特征的软阈值化
作者 | 哈尔滨工业大学(威海)讲师 赵明航本文解读了一种新的深度注意力算法,即深度残差收缩网络(Deep Residual Shrinkage Network)。从功能上讲,深度残差收缩网络是一种面向强噪声或者高度冗余数据的特征学…

如何在同一台电脑上多个账户同时登陆MSN
一般情况下,在一台电脑上只能启动一个msn进程,所以当想多个账户在同一台电脑上同时登陆时,就无法实现了。我们可以使用MSNShell来实现多个账户的同时登陆。MSNShell下载地址:http://www.msnshell.netMSNShell系统要求:…