0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看威廉希尔官方网站 视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何使用tcmalloc来替换glibc的malloc

科技绿洲 来源:Linux开发架构之路 作者:Linux开发架构之路 2023-11-11 16:52 次阅读

代码中使用tcmalloc替换malloc

我们如何使用tcmalloc来替换glibc的malloc呢?

在链接tcmalloc的时候我们可以使用以下任意一种方式:

1.启动程序之前,预先加载tcmalloc动态库的环境变量设置:exportLD_PRELOAD="
/usr/local/lib/libtcmalloc.so"

2.在你的动态库链接的地方加入:-ltcmalloc

检测内存泄漏

測试代码1:

#include < iostream >
using namespace std;
int main()
{
        int *p = new int();
        return 0;
}

编译:g++ t.cpp -o main -ltcmalloc -g -O0

内存泄漏检查:env HEAPCHECK=normal ./main

结果:

root@ubuntu:/home/gaoke/test# env HEAPCHECK=normal ./main
WARNING: Perftools heap leak checker is active -- Performance may suffer
Have memory regions w/o callers: might report false leaks
Leak check _main_ detected leaks of 4 bytes in 1 objects
The 1 largest leaks:
*** WARNING: Cannot convert addresses to symbols in output below.
*** Reason: Cannot find 'pprof' (is PPROF_PATH set correctly?)
*** If you cannot fix this, try running pprof directly.
Leak of 4 bytes in 1 objects allocated from:
  @ 4007ef 
  @ 7f7895a64f45 
  @ 400719 


If the preceding stack traces are not enough to find the leaks, try running THIS shell command:

pprof ./main "/tmp/main.6712._main_-end.heap" --inuse_objects --lines --heapcheck  --edgefraction=1e-10 --nodefraction=1e-10 --gv

If you are still puzzled about why the leaks are there, try rerunning this program with HEAP_CHECK_TEST_POINTER_ALIGNMENT=1 and/or with HEAP_CHECK_MAX_POINTER_OFFSET=-1
If the leak report occurs in a small fraction of runs, try running with TCMALLOC_MAX_FREE_QUEUE_SIZE of few hundred MB or with TCMALLOC_RECLAIM_MEMORY=false, it might help find leaks more repeatably
Exiting with error code (instead of crashing) because of whole-program memory leaks

大家注意,这里有关键字Leak,你就得当心这里可能存在内存泄漏,提示

Leak of 4 bytes in 1 objects allocated from

对,是有四字节的内存泄漏,虽然你看代码能看到指针p未释放,但是这里你需要掌握的是在你无法直观的通过阅读代码来找到内存泄漏点的情况下,如何用tcmalloc工具来分析问题。

相信细心的你会注意到运行输出的这一行

pprof ./main "/tmp/main.6712. main -end.heap" --inuse_objects --lines --heapcheck --edgefraction=1e-10 --nodefraction=1e-10 --gv

这里就是我要重点讲的pprof工具

google-perftool提供了一个叫pprof的工具,它是一个perl的脚本,通过这个工具,可以将google-perftool的输出结果分析得更为直观,输出为text、图片、pdf等格式。

这里我们把结果通过text的方式输出:你只需要把刚才的--gv换成--text

pprof ./main "/tmp/main.6712. main -end.heap" --inuse_objects --lines --heapcheck --edgefraction=1e-10 --nodefraction=1e-10 --text

图片

好了,你可以看到这里已经很明显了,给你提示了t.cpp文件的第五行代码存在内存泄漏(当然你也可以输出其他格式,raw,png,pdf等等,whatever,只要可以帮助你去分析问题解决问题)。

实际上项目中遇到的内存泄漏问题是异常复杂的,我给的这个示例只是小试牛刀。项目常见的内存泄漏点大家都清楚,new了但是没有得到delete,但是要根据pprof工具对应的函数,代码行找到对应的泄漏点你可能需要花费点功夫。

实际上你的大多数应用都是以服务的方式启动,长时间处于作业/工作状态。你需要定期来检测下内存泄漏情况,那么这时你需要显示的调用接口来输出leak情况,

示例代码2

bool memory_check(void* arg)
{
    HeapLeakChecker::NoGlobalLeaks();
    return TRUE;
}

将上面的代码加到你的定时检测逻辑里,或者需要观察的点,那么他就会输出示例1中的内容,动态的帮助你分析内存泄漏点。

分析使用tcmalloc后内存暴涨不降问题

记得几年前我开始推广大家使用tcmalloc后,一些同事做压测过程中也遇到了不少麻烦。比如当有大量数据过来,new出来很多的大块内存,突然发现有时候内存增长到几个G,开始以为是内存泄露的问题。

图片

先是用tcmalloc环境变量来检查内存泄漏没有找到泄漏的报告,用valgrind也做了大量的测试,但是valgrind显示没有内存泄露。 实际上遇到这种问题不要慌,基本上是对tcmalloc使用上的问题,你要知道默认情况下,tcmalloc会将长时间未用的内存交还系统。tcmalloc_release_rate这个flag控制了这个交回频率。你可以在运行时通过这个语句强制这个release发生:

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

当然了,你可以通过 SetMemoryReleaseRate() 来设置这个tcmalloc_release_rate. 如果设置为0,代表永远不交回。数字越大代表交回的频率越大。一般合理的值就是设置一个0 - 10 之间的一个数。也可以通过设置环境变量 TCMALLOC_RELEASE_RATE来设置这个rate。

实际上我估计很多人看了官网说的

MallocExtension::instance()->SetMemoryReleaseRate(7.0);

很疑惑,我曾经带着疑惑做了测试,发现SetMemoryReleaseRate设置9,10回收的内存仍然是很慢的,所以后来我索性在进程启动的开始设置SetMemoryReleaseRate为9,然后在new对象的时候ReleaseFreeMemory,在new对象析构的时候ReleaseFreeMemory一次 (new出来的对象可能从new到delete的生命周期是不确定的,可能存在1天?4小时?30分钟都有可能,而且不是频繁的释放和销毁),因此这种情况下,内存就比较及时的回收了,所以大家可以根据自己的项目逻辑来选择ReleaseFreeMemory的时机,最好不要频繁的申请和释放,这对tcmalloc来说也是难受。

图片

所以你不仅仅要关注tcmalloc申请大小内存块,还要关注内存块的在合适的时间及时回收,否则造成内存占用过高。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 内存
    +关注

    关注

    8

    文章

    3024

    浏览量

    74038
  • Glibc
    +关注

    关注

    0

    文章

    9

    浏览量

    7500
  • 动态库
    +关注

    关注

    0

    文章

    17

    浏览量

    6224
  • malloc
    +关注

    关注

    0

    文章

    52

    浏览量

    73
收藏 人收藏

    评论

    相关推荐

    当你malloc(0)时会发生什么

    。换言之,没事儿不要吃饱了撑的在实际编程中写下 malloc(0) 这种天怒人怨的代码。但是,这个无意义的问题吸引了我的兴趣。因此笔者开始查阅 glibc 的源代码,依此了解在 glibc 下
    发表于 12-01 10:42 489次阅读

    Yocto Bitbake Glibc构建失败了怎么解决?

    我正在尝试构建 Yocto 映像,但在编译 glibc 时构建失败。我运行了这个命令:bitbake 精简版图像我收到如下编译错误: | /media/ubu/LocalDisk
    发表于 03-24 08:01

    全志Tina Linux下如何编译glibc

    ./env.sh 注意下信息,我们可以看到glibc生成准备环境时候,已经使用了我们指定gcc工具链,make工具。 编译完成后,我们看到对应so库 替换glibc,例如在我们测试demo,修改
    发表于 06-02 10:00

    使用全志方案遇到glibc库版本低以及编译报错的解决方法

    env.sh脚本 env.sh ./env.sh 注意下信息,我们可以看到glibc生成准备环境时候,已经使用了我们指定gcc工具链,make工具。 编译完成后,我们看到对应so库 替换glibc
    发表于 06-25 09:48

    通过实现一个简单的malloc描述malloc背后的机制

    任何一个用过或学过C的人对malloc都不会陌生。大家都知道malloc可以分配一段连续的内存空间,并且在不再使用时可以通过free释放掉。但是,许多程序员对malloc背后的事情并不熟悉,许多人
    的头像 发表于 01-27 23:30 4206次阅读
    通过实现一个简单的<b class='flag-5'>malloc</b><b class='flag-5'>来</b>描述<b class='flag-5'>malloc</b>背后的机制

    在嵌入式设备中使用Malloc Hook的试验

    在嵌入式设备中,计划使用malloc hook进行内存跟踪,以便测试程序的内存使用。 试验1: 在程序开始,增加了mtrace函数,定义环境变量MALLOC_TRACE。 发现了
    发表于 04-02 14:37 696次阅读

    glibc内存管理存在的共性问题及解决方法

    引言 对于嵌入式设备来说,用户态内存管理是一项基础功能,目前主流的用户态内存管理库有glibc、uclibc、tcmalloc、jemalloc等。 本文基于glibc2.17版本进行分析,围绕
    的头像 发表于 06-18 14:50 3256次阅读

    Glibc内存管理之Ptmalloc2源代码分析

    Glibc内存管理之Ptmalloc2源代码分析
    发表于 07-29 09:20 24次下载

    malloc和free简介及实现方式说明

    malloc 分配指定大小的内存空间,返回一个指向该空间的指针。大小以字节为单位。返回 void* 指针,需要强制类型转换后才能引用其中的值。 free 释放一个由 malloc 所分配的内存空间。ptr 指向一个要释放内存的内存块,该指针应当是之前调用的
    的头像 发表于 05-14 09:56 4556次阅读
    <b class='flag-5'>malloc</b>和free简介及实现方式说明

    如何调试glibc

    对于GNU工具链开发者而言,为了获取到一些动态重定位、函数符号解析的信息,开发者通常需要对Glibc中的动态链接器程序进行调试,一般会利用gdb进行调试
    的头像 发表于 05-11 09:03 906次阅读

    jemalloc分配机制的介绍及其优化实践

    C/C++通过libc做内存分配。glibc中默认的分配机制是ptmalloc。除此之外,还有众多的不同侧重的优化,例如tcmalloc,jemalloc。
    的头像 发表于 05-30 09:12 1171次阅读
    jemalloc分配机制的介绍及其优化实践

    面试题:malloc(0)会发生什么?

    至此,我们就可以根据这些计算出使用 glibc 在我们的电脑上运行时 malloc 出的最小空间的大小了。计算完后,还可以根据 malloc_usable_size 判断自己的计算是否正确,样例代码如下
    的头像 发表于 10-31 16:27 527次阅读
    面试题:<b class='flag-5'>malloc</b>(0)会发生什么?

    TCMalloc 的架构设计细节

    本节将专注于TCMalloc 的架构设计细节,整体看一下TCMalloc 的设计特性。 主要的几个特性如下: 高性能。大多数对象的分配和释放都不需要产生太多的竞争,因为tcmalloc
    的头像 发表于 11-09 10:18 414次阅读
    <b class='flag-5'>TCMalloc</b> 的架构设计细节

    malloc跟free的源码分析

    malloc 本文梳理了一下malloc跟free的源码。malloc()函数在源代码中使用宏定义为public_mALLOc()。public_m
    的头像 发表于 11-09 11:39 1640次阅读

    如何实现一个malloc

    甚至把malloc当做操作系统所提供的系统调用或C的关键字。实际上,malloc只是C的标准库中提供的一个普通函数,而且实现malloc的基本思想并不复杂,任何一个对C和操作系统有些许了解的程序员都可以很容易理解。 这篇文章通过
    的头像 发表于 11-13 14:31 783次阅读
    如何实现一个<b class='flag-5'>malloc</b>