You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ubuntu Linux下malloc hooks移除后如何统计malloc调用次数

大型C++项目malloc调用次数统计方案

按操作成本从低到高列两个可直接落地的方案,不需要复杂配置:


方案1:零代码修改,用Valgrind Callgrind实现(适合短时间运行的场景)

你之前选错了Valgrind的工具,Massif本身只做堆内存占用剖析,不统计调用次数,用Callgrind可以直接拿到计数,不需要改项目代码、不需要重新编译:

  • 执行以下命令启动你的程序:
    valgrind --tool=callgrind --toggle-collect=malloc ./your_program [your_program_args]
    
  • 程序运行结束后,当前目录会生成callgrind.out.<pid>格式的结果文件,执行以下命令即可直接看到malloc总调用次数:
    callgrind_annotate callgrind.out.<pid> | grep "malloc"
    

注意:该方案会让程序运行速度下降10~30倍,如果你的项目全量流程运行时间很长,选第二个方案。


方案2:LD_PRELOAD预加载计数库(性能损耗极低,适合大型项目全量运行)

这个方案实现非常简单,不需要改原有项目的代码,性能损耗在5%以内:

  • 新建一个名为malloc_count.c的文件,写入以下代码:
    #define _GNU_SOURCE
    #include <stdio.h>
    #include <stdlib.h>
    #include <dlfcn.h>
    
    static unsigned long long malloc_cnt = 0;
    static void* (*real_malloc)(size_t) = NULL;
    
    void *malloc(size_t size) {
        if (!real_malloc) {
            real_malloc = dlsym(RTLD_NEXT, "malloc");
        }
        malloc_cnt++;
        return real_malloc(size);
    }
    
    __attribute__((destructor))
    static void print_result() {
        fprintf(stderr, "\nTotal malloc calls: %llu\n", malloc_cnt);
    }
    
  • 编译成动态库:
    gcc -shared -fPIC -o libmcount.so malloc_count.c -ldl
    
  • 启动你的程序时前置环境变量加载这个库即可,程序正常退出时会自动在错误流打印总调用次数:
    LD_PRELOAD=./libmcount.so ./your_program [your_program_args]
    

说明:glibc环境下C++的new默认底层调用malloc,这个计数会包含new触发的malloc请求,如果需要区分可以自行在库里加栈判断逻辑。


此前尝试方案的问题说明

  • __malloc_hook 机制从glibc 2.34版本开始已被正式移除,新发行版系统上无法兼容,不需要再尝试该方案。
  • Valgrind Massif的设计目标是统计堆内存峰值、分配栈占比,本身不提供调用次数统计能力,没有相关配置项可以开启该功能。

内容的提问来源于stack exchange,提问作者Andreas Pasternak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 02:42:28