自动化与脚本
在 Linux 上用 heaptrack 定位堆分配热点…
当需要在 Linux 上追踪堆分配、查找内存泄漏、测量峰值堆内存、识别分配热点或对比两次运行分配行为时使用 heaptrack。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 59/100 ×0.15
适用场景
在 Linux 上用 heaptrack特定
解决思路
- 安装 heaptrack(Ubuntu/Debian):运行 `sudo apt-get install heaptrack heaptrack-gui`。
- 安装 heaptrack(Fedora):运行 `sudo dnf install heaptrack`。
- 安装 heaptrack(Arch):运行 `sudo pacman -S heaptrack`。
- 从源码构建 heaptrack:`git clone https://github.com/KDE/heaptrack.git`;`cmake -S heaptrack -B heaptrack-build -DCMAKE_BUILD_TYPE=Release`;`cmake --build heaptrack-build -j$(nproc)`。
- 分析程序:运行 `heaptrack ./myapp arg1 arg2`,会生成 `heaptrack.<prog>.<pid>.zst`。
- 附加到运行中的进程:运行 `heaptrack --pid 12345`。
- 分析 trace 文件:运行 `heaptrack_print heaptrack.myapp.12345.zst`。
- GUI 分析:如果安装了 heaptrack-gui,运行 `heaptrack_gui heaptrack.myapp.12345.zst`。
- 为了更好地 profiling 而构建:运行 `cmake -S . -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo`,再运行 `cmake --build build`。
- 用调试符号构建后,运行 `heaptrack ./build/myapp` 进行 profile。
- 读取 heaptrack_print 输出:运行 `heaptrack_print heaptrack.myapp.*.zst 2>/dev/null`。
- 关注输出中的关键段:`total runtime`、`calls to allocation functions`、`temporary allocations`、`peak heap memory consumption`、`peak RSS (including heap)`、`total memory leaked`、按峰值内存排序的 top allocation hotspots、top leaked allocations。
- 解读指标 `total memory leaked`:已分配但从未释放的内存。
- 解读指标 `peak heap consumption`:任意时刻存活堆内存的最大值。
- 解读指标 `temporary allocations`:在同一次调用栈内分配后又释放的分配。
- 解读指标 `calls to allocation functions`:malloc/new/realloc 调用总数。
- 显示 top N hotspots:运行 `heaptrack_print -p 10 heaptrack.myapp.*.zst`。
- 生成 flamegraph 数据:运行 `heaptrack_print -f heaptrack.myapp.*.zst > alloc.folded`,再用 `flamegraph.pl alloc.folded > alloc.svg` 生成 SVG。
- 只显示泄漏的分配:运行 `heaptrack_print -l heaptrack.myapp.*.zst`。
- 只显示超过阈值的分配:运行 `heaptrack_print --min-cost 1048576 heaptrack.myapp.*.zst`(仅 >1MB)。
- 显示简短摘要:运行 `heaptrack_print -s heaptrack.myapp.*.zst`。
- 对比两次运行:记录基线,运行 `heaptrack ./myapp --config baseline.conf`,再运行 `mv heaptrack.myapp.*.zst before.zst`。
- 对比两次运行:修改后再次记录,运行 `heaptrack ./myapp --config new.conf`,再运行 `mv heaptrack.myapp.*.zst after.zst`。
- 对比两次运行:比较热点差异,运行 `heaptrack_print before.zst | head -20 > before.txt`、`heaptrack_print after.zst | head -20 > after.txt`、`diff before.txt after.txt`。
- 工具选择:大多数情况用 heaptrack;需要平台可移植性或详细快照对比时用 Valgrind massif。heaptrack 开销约 2-3x,massif 约 20x;heaptrack 输出为压缩 trace + GUI,massif 为文本/ms_print;两者都支持泄漏检测、峰值跟踪、时间视图、完整调用栈;heaptrack 仅 Linux,massif 支持 Linux 和 macOS;两者都不需要重新编译。
- Rust 集成:让 heaptrack 能拦截 Rust 分配,使用系统分配器:`use std::alloc::System; #[global_allocator] static A: System = System;`。
- Rust 集成:profile Rust 二进制,运行 `cargo build --release`,再运行 `heaptrack ./target/release/myapp`。
- Rust 集成:为改善回溯,构建带调试符号,运行 `cargo build --profile release-with-debug`,再运行 `heaptrack ./target/release-with-debug/myapp`。
- 参考:heaptrack_print 输出参考和 GUI 用法见 `references/heaptrack-analysis.md`。
- 相关技能:Memcheck(正确性)和 massif(替代堆 profiler)用 `skills/profilers/valgrind`;CPU profiling 配合 `skills/profilers/linux-perf`;Rust 专用分配 profiling 用 `skills/rust/rust-profiling`;无 profiling 开销的泄漏检测用 `skills/runtimes/sanitizers` 的 ASan LeakSanitizer。
适用边界 · 注意事项
- 非 Linux 平台或需要 macOS 可移植性时,不要用 heaptrack,改用 Valgrind massif。
- 需要非常详细的快照对比时,优先 Valgrind massif;heaptrack 更适合大多数 heap profiling。
- Rust 使用自定义全局分配器而非 System 分配器时,heaptrack 无法正确拦截分配;仅需内存正确性/泄漏检测且不想承担 profiling 开销时,考虑 Valgrind Memcheck 或 ASan LeakSanitizer。