C++程序内存占用过高排查:如何统计各对象的内存占比?
C++ 类MAT内存分析方案(适配macOS/Linux)
macOS 优先可用方案
Instruments 进阶用法(无需额外安装工具)
你已经安装过Instruments,只要调整配置即可拿到具体C++对象的内存占比数据:
- 打开Instruments选择Allocations分析模板,启动目标程序到需要统计的特定时刻
- 点击顶部操作栏的Mark Generation按钮生成当前堆的内存快照
- 展开快照条目选择All Allocations,在右侧分组设置中把展示维度切换为Object Type,即可看到所有类型对象的总内存占用、实例数、占比
- 针对
vector<shared_ptr<MyObject>>这类容器的总持有内存统计,可以开启Record reference counts选项,筛选所有关联的MyObject实例做自动聚合,也可以自定义符号过滤规则直接统计指定容器关联的总内存占比
jemalloc 堆转储方案
- 通过brew安装jemalloc库,编译你的程序时链接jemalloc替代系统默认分配器
- 运行程序时添加环境变量
MALLOC_CONF=prof:true,prof_prefix:heap_dump.out - 到需要统计的时刻给进程发送SIGUSR2信号,即可生成当前时刻的堆转储文件
- 用jeprof工具分析转储文件,可直接输出各类型内存占比、分配堆栈、火焰图等数据
Linux 平台可用方案
- 首推heaptrack:编译程序时添加
-g参数保留调试符号,执行heaptrack ./目标程序启动程序,到指定时刻停止运行即可生成分析报告,用heaptrack_gui打开报告可以直观看到各类型对象、容器的总内存占比,支持按类型、分配堆栈过滤,完全满足你需要的特定容器内存占比统计需求 - Google perftools tcmalloc:编译时链接tcmalloc库,运行时开启堆profiling生成转储文件,用pprof工具可输出文本格式的占比统计、可视化内存占用图
- 核心转储分析:用gdb的
gcore命令生成指定时刻的进程核心转储,配合valgrind massif、massif-visualizer做离线分析,适合小内存程序的场景
轻量侵入式方案(跨平台)
如果不想引入第三方工具,可以自定义重载operator new和operator delete,在分配/释放内存的逻辑中维护各类型的实例计数、总占用大小,运行时可以随时输出各类型的内存占比,代码侵入性低,适合对自定义类型做定向统计的场景。
内容的提问来源于stack exchange,提问作者nybon
相关产品推荐
相关产品推荐

