Linux | c&cpp | Email | github | QQ群:425043908 关注本站

itarticle.cc

您现在的位置是:网站首页 -> 游戏相关 文章内容

TCMalloc的使用与源码剖析(安装和使用)-itarticl.cc-IT技术类文章记录&分享

发布时间: 5年前游戏相关 100人已围观返回

1、安装

Linux下tcmalloc的安装过程如下:

1) 从Google源代码网址上下载源代码包,现在最新版本为2.0;

2) 解压缩源代码包

# unzip gperftools-2.0.zip 或

# tar zxvf gperftools-2.0.tar.gz

3) 编译动态库

# cd gperftools-2.0

# ./ configure --disable-cpu-profiler --disable-heap-profiler--disable-heap-checker

--disable-debugalloc--enable-minimal

加入上面的参数是为了只生成tcmalloc_minimal动态库,如果需要所有组件,命令如下:

# ./configure

# ./configure-h 用于查看编译选项。

编译和安装

# make&& make install

使用最小安装时把tcmalloc_minimal的动态库拷贝到系统目录中:

# cplib/tcmalloc_minimal.so.0.0.0 /usr/local/lib

创建软连接指向tcmalloc:

# ls –s/usr/local/lib/libtcmalloc_minimal.so.0.0.0 /usr/local/lib/libtcmalloc.so

启动程序之前,预先加载tcmalloc动态库的环境变量设置:

# exportLD_PRELOAD=”/usr/local/lib/libtcmalloc.so

使用losf检查程序是否已经加载tcmalloc库:

# lsof -n | greptcmalloc

在Linux下使用的tcmalloc安装完成,在Windows下使用VS(2003以上版本)打开工程项目gperftools.sln进行编译。


使用

将libtcmalloc.so/libtcmalloc.a链接到程序中,或者设置LD_PRELOAD=libtcmalloc.so。这样就可以使用tcmalloc库中的函数替换掉操作系统的malloc、free、realloc、strdup内存管理函数。可以设置环境变量设置如下:

TCMALLOC_DEBUG=<level> 调试级别,取值为1-2

MALLOCSTATS=<level> 设置显示内存使用状态级别,取值为1-2

HEAPPROFILE=<pre> 指定内存泄露检查的数据导出文件

HEAPCHECK=<type> 堆检查类型,type=normal/strict/draconian

TcMalloc库还可以进行内存泄露的检查,使用这个功能有两种方法:

1)将tcmalloc库链接到程序中,注意应该将tcmalloc库最后链接到程序中;

2)设置LD_PRELOAD=”libtcmalloc.so”/HEAPCHECK=normal,这样就不需重新编译程序

打开检查功能,有两种方式可以开启泄露检查功能:

1) 使用环境变量,对整个程序进行检查: HEAPCHECK=normal /bin/ls

2) 在源代码中插入检查点,这样可以控制只检查程序的某些部分,代码如下:

HeapProfileLeakCheckerchecker("foo"); // 开始检查

Foo(); //需要检查的部分

assert(checker.NoLeaks()); // 结束检查


调用checker建立一个内存快照,在调用checker.NoLeaks建立另一个快照,然后进行比较,如果内存有增长或者任意变化,NoLeaks函数返回false,并输出一个信息告诉你如何使用pprof工具来分析具体的内存泄露。

执行内存检查:

#LD_PRELOAD=libtcmalloc.so HEAPCHECK=strict HEAPPROFILE=memtm ./a.out

执行完成后会输出检查的结果,如果有泄露,pprof会输出泄露多少个字节,有多少次分配,也会输出详细的列表指出在什么地方分配和分配多少次。

分析输出:

#pprof $JAVA_HOME/bin/java --text /tmp/memTrack.0026.heap > ~/HeapFile/memTrack.txt

比较两个快照:

#pprof --base=profile.0001.heap 程序名 profile.0002.heap

已知内存泄漏时,关闭内存泄露检查的代码:

void *mark =HeapLeakChecker::GetDisableChecksStart();

<leaky code> //不做泄漏检查的部分

HeapLeakChecker::DisableChecksToHereFrom(mark);

注:在某些libc中程序可能要关闭检查才能正常工作。

注:不能检查数组删除的内存泄露,比如:char *str = new char[100]; delete str;。


修改运行时行为

您可以通过环境变量更好地控制tcmalloc的行为。

一般有用的标志:

TCMALLOC_SAMPLE_PARAMETER

默认值:0


采样动作之间的近似差距。也就是说,我们每个tcmalloc_sample_parmeter分配字节大约采样一次。可通过MallocExtension::GetHeapSample()或获得此采样堆信息。MallocExtension::ReadStackTraces()。合理的值为524288。

TCMALLOC_RELEASE_RATE

默认值:1.0


在madvise(MADV_DONTNEED)支持它的系统上,通过释放未使用的内存到系统的速率。零表示我们永远不会将内存释放回系统。增加此标志可以更快地返回内存;减少它以更慢地返回内存。合理的比率在[0,10]范围内。

TCMALLOC_LARGE_ALLOC_REPORT_THRESHOLD

默认值:1073741824


大于此值的分配将导致堆栈跟踪转储到stderr。每次我们打印一条消息时,转储堆栈跟踪的阈值将增加1.125倍,以便每60条消息,阈值将自动增加约1000倍。这限制了此标志生成的额外日志记录的数量。该标志的默认值非常大,因此除非覆盖该标志,否则您将看不到任何额外的日志记录。

TCMALLOC_MAX_TOTAL_THREAD_CACHE_BYTES

默认值:16777216


约束分配给线程缓存的字节总数。此界限不是严格的,因此在某些情况下缓存可能会超过此界限。该值默认为16MB。对于具有多个线程的应用程序,这可能不是足够大的缓存,这可能会影响性能。如果您怀疑由于TCMalloc中的锁争用而导致应用程序无法扩展到多个线程,则可以尝试增加此值。这可能会提高性能,但以TCMalloc占用额外的内存为代价。有关更多详细信息,请参见垃圾回收。

高级“ tweaking”标志,可更精确地控制tcmalloc如何尝试从内核分配内存。

TCMALLOC_SKIP_MMAP

默认值:false


如果为true,请不要尝试用于mmap从内核获取内存。

TCMALLOC_SKIP_SBRK

默认值:false

如果为true,请不要尝试用于sbrk从内核获取内存。

TCMALLOC_DEVMEM_START

默认值:0


用于/dev/mem

分配的物理内存起始位置(以MB为单位)。将此设置为0将禁用/dev/mem

分配。

TCMALLOC_DEVMEM_LIMIT

默认值:0


用于/dev/mem

分配的物理内存限制位置(以MB为单位)。将此设置为0表示没有限制。

TCMALLOC_DEVMEM_DEVICE

默认值:/ dev / mem


用于分配非托管内存的设备。

TCMALLOC_MEMFS_MALLOC_PATH

默认值:“”


如果已设置,请指定安装了ugeltlbfs或tmpfs的路径。这可以允许更快的分配。

TCMALLOC_MEMFS_LIMIT_MB

默认值:0


将总memfs分配大小限制为指定的MB数。0表示“无限制”。

TCMALLOC_MEMFS_ABORT_ON_FAIL

默认值:false


如果为true,则每当memfs_malloc未能满足分配时,则中止()。

TCMALLOC_MEMFS_IGNORE_MMAP_FAIL

默认值:false


如果为true,则忽略mmap的失败。

TCMALLOC_MEMFS_MAP_PRIVATE

默认值:false


如果为true,则通过memfs而不是MAP_SHARED映射时使用MAP_PRIVATE。

修改代码中的行为的MallocExtension类

malloc_extension.h提供了一些旋钮,您可以在程序中对其进行调整,以影响tcmalloc的行为。

将内存释放回系统

默认情况下,tcmalloc会随着时间的推移逐渐将不再使用的内存释放回内核。该tcmalloc_release_rate标志控制如何快速发生这种情况。您还可以在程序执行中的给定时间点强制释放,如下所示:

MallocExtension :: instance()-> ReleaseFreeMemory();


您还可以调用在运行时SetMemoryReleaseRate()更改

tcmalloc_release_rate值,或

GetMemoryReleaseRate查看当前的释放速率。


内存自省

有几种例程可以使人理解形式的当前内存使用情况:

MallocExtension :: instance()-> GetStats(buffer,buffer_length);

MallocExtension :: instance()-> GetHeapSample(&string);

MallocExtension :: instance()-> GetHeapGrowthStacks(&string);


最后两个创建文件的格式与heap-profiler相同,并且可以作为数据文件传递给pprof。第一个是人类可读的,用于调试。

通用Tcmalloc状态

TCMalloc支持设置和检索任意“属性”:

MallocExtension :: instance()-> SetNumericProperty(property_name,value);

MallocExtension :: instance()-> GetNumericProperty(property_name,&value);

应用程序可以设置和获取这些属性,但是最有用的是库设置属性时,应用程序可以读取它们。这是TCMalloc定义的属性;

MallocExtension::instance()->GetNumericProperty("generic.heap_size",&value);:


generic.current_allocated_bytes


应用程序使用的字节数。这通常不匹配操作系统报告的内存使用情况,因为它不包括TCMalloc开销或内存碎片。

generic.heap_size


TCMalloc保留的系统内存字节。

tcmalloc.pageheap_free_bytes


页面堆中空闲的映射页面中的字节数。这些字节可用于满足分配请求。它们始终计入虚拟内存使用率,并且除非操作系统将基础内存换出,否则它们也计入物理内存使用率。

tcmalloc.pageheap_unmapped_bytes


页面堆中未映射的空闲页面中的字节数。这些字节可能已经通过MallocExtension“释放”调用之一释放回了操作系统。它们可用于满足分配请求,但通常会导致页面错误。它们始终计入虚拟内存使用情况,并且取决于操作系统,通常不计入物理内存使用情况。

tcmalloc.slack_bytes

pageheap_free_bytes和pageheap_unmapped_bytes的总和。仅提供向后兼容性。不使用。

tcmalloc.max_total_thread_cache_bytes


TCMalloc为小对象专用的内存量有一个限制。在某些情况下,较高的数字会折衷更多的内存使用量,从而提高了效率。


tcmalloc.current_total_thread_cache_bytes

TCMalloc使用的某些内存的度量(用于小对象)。

发布时间: 5年前游戏相关100人已围观返回回到顶端

很赞哦! (1)

文章评论

  • 请先说点什么
    热门评论
    99人参与,0条评论

站点信息

  • 建站时间:2016-04-01
  • 文章统计:728条
  • 文章评论:82条
  • QQ群二维码:扫描二维码,互相交流