
Heaptrack
- 325 installs
- 155 repo stars
- Updated June 27, 2026
- mohitmishra786/low-level-dev-skills
Profile heap allocations and leaks in native apps before release or during perf regressions to find hot alloc sites, peak memory, and unnecessary churn.
About
heaptrack skill covers Linux heap profiling for C/C++ binaries: recording allocation stacks, visualizing peak usage, comparing builds for regressions, and tying memory churn to source paths during ship-stage performance hardening of CLI, API, and game services.
- Allocation stack attribution
- Peak and transient heap timelines
- Compare runs across commits
- Leak-oriented sampling modes
- Low-overhead native tracing
Heaptrack by the numbers
- 325 all-time installs (skills.sh)
- +22 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #125 of 596 Debugging skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/mohitmishra786/low-level-dev-skills --skill heaptrackAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 325 |
|---|---|
| repo stars | ★ 155 |
| Last updated | June 27, 2026 |
| Repository | mohitmishra786/low-level-dev-skills ↗ |
What it does
Profile heap allocations and leaks in native apps before release or during perf regressions to find hot alloc sites, peak memory, and unnecessary churn.
Files
heaptrack
Purpose
Guide agents through heaptrack for heap allocation profiling on Linux: recording allocation traces, analysing with heaptrack_print, identifying leaks and hotspots, and comparing runs.
Triggers
- "How do I find memory allocation hotspots in my C++ program?"
- "My program uses too much memory — how do I find where?"
- "How do I use heaptrack to detect memory leaks?"
- "What is heaptrack and how does it differ from Valgrind massif?"
- "How do I compare memory usage between two program versions?"
- "heaptrack_print output — how do I interpret it?"
Workflow
1. Installation
# Ubuntu/Debian
sudo apt-get install heaptrack heaptrack-gui
# Fedora
sudo dnf install heaptrack
# Arch
sudo pacman -S heaptrack
# Build from source
git clone https://github.com/KDE/heaptrack.git
cmake -S heaptrack -B heaptrack-build -DCMAKE_BUILD_TYPE=Release
cmake --build heaptrack-build -j$(nproc)2. Basic usage
# Profile a program (generates heaptrack.<prog>.<pid>.zst)
heaptrack ./myapp arg1 arg2
# Attach to running process
heaptrack --pid 12345
# Analyse the trace file
heaptrack_print heaptrack.myapp.12345.zst
# GUI analysis (if heaptrack-gui installed)
heaptrack_gui heaptrack.myapp.12345.zst3. Build for better profiling
# Build with debug symbols (essential for readable backtraces)
cmake -S . -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo
cmake --build build
# Then profile
heaptrack ./build/myapp4. Interpreting heaptrack_print output
heaptrack_print heaptrack.myapp.*.zst 2>/dev/nullKey sections:
total runtime: 2.34s
calls to allocation functions: 145,234 (62,064/s)
temporary allocations: 89,123 (38,087/s)
peak heap memory consumption: 45.23MB
peak RSS (including heap): 78.45MB
total memory leaked: 2.34MB
# Top allocation hotspots (by peak memory)
hotspot 1: 12.34MB peak
myapp::cache::Cache::insert(...)
at src/cache.cpp:142
...
# Top leaked allocations
leak 1: 2.34MB leaked in 1,234 allocations
myapp::connection::Connection::new(...)
at src/connection.cpp:67| Metric | Meaning |
|---|---|
total memory leaked | Memory allocated but never freed |
peak heap consumption | Maximum live heap at any point |
temporary allocations | Allocated and freed within one call stack |
calls to allocation functions | Total malloc/new/realloc calls |
5. Filtering and analysis options
# Show top N hotspots
heaptrack_print -p 10 heaptrack.myapp.*.zst # top 10 hotspots
# Show flamegraph data
heaptrack_print -f heaptrack.myapp.*.zst > alloc.folded
flamegraph.pl alloc.folded > alloc.svg
# Show only leaked allocations
heaptrack_print -l heaptrack.myapp.*.zst
# Show allocations above threshold
heaptrack_print --min-cost 1048576 heaptrack.myapp.*.zst # >1MB only
# Short summary
heaptrack_print -s heaptrack.myapp.*.zst6. Comparing two runs
# Record baseline
heaptrack ./myapp --config baseline.conf
mv heaptrack.myapp.*.zst before.zst
# Make changes, record again
heaptrack ./myapp --config new.conf
mv heaptrack.myapp.*.zst after.zst
# Compare (shows diff of hotspots)
heaptrack_print before.zst | head -20 > before.txt
heaptrack_print after.zst | head -20 > after.txt
diff before.txt after.txt7. heaptrack vs Valgrind massif
| Feature | heaptrack | Valgrind massif |
|---|---|---|
| Overhead | ~2-3x | ~20x |
| Output | Compressed trace + GUI | Text/ms_print |
| Leak detection | Yes | Yes |
| Peak tracking | Yes | Yes |
| Temporal view | Yes (GUI) | Yes (ms_print) |
| Platform | Linux only | Linux, macOS |
| Needs recompile | No | No |
| Call graph | Full stack traces | Full stack traces |
Use heaptrack for most cases; use massif when you need platform portability or detailed snapshot comparison.
8. Integration with Rust
heaptrack works with Rust binaries when using the system allocator:
// Rust: use system allocator so heaptrack can intercept
use std::alloc::System;
#[global_allocator]
static A: System = System;# Profile Rust binary
cargo build --release
heaptrack ./target/release/myapp
# Note: debug symbols improve backtraces
cargo build --profile release-with-debug
heaptrack ./target/release-with-debug/myappFor heaptrack_print output reference and GUI usage, see references/heaptrack-analysis.md.
Related skills
- Use
skills/profilers/valgrindfor Memcheck (correctness) and massif (alternative heap profiler) - Use
skills/profilers/linux-perffor CPU profiling alongside memory profiling - Use
skills/rust/rust-profilingfor Rust-specific allocation profiling approaches - Use
skills/runtimes/sanitizers— ASan LeakSanitizer for leak detection without profiling overhead
heaptrack Analysis Reference
heaptrack_print Complete Options
heaptrack_print [options] <heaptrack.data.zst>
Options:
-p, --print-peaks N Print top N peak allocation hotspots (default: 10)
-a, --print-allocs N Print top N allocation count hotspots
-t, --print-temporary N Print top N temporary allocation hotspots
-l, --print-leaks N Print top N leaked allocation hotspots
-s, --short Only print summary
-f, --flamegraph Print flamegraph-compatible folded stacks
-m, --minimum-cost N Only show stacks with cost >= N bytes
--help Show helpOutput Sections Explained
total runtime: 5.23s
calls to allocation functions: 1,234,567 (236,049/s)
temporary allocations: 987,654 (188,847/s)
peak heap memory consumption: 123.45MB
peak RSS (including heap): 256.78MB
total memory leaked: 4.56MB| Line | What to watch |
|---|---|
calls to allocation functions | Very high count = excessive small allocations |
temporary allocations | High % of total = allocation churn (use pools/arenas) |
peak heap consumption | Actual max heap; compare to your memory budget |
peak RSS | Includes mmap, stack, code; typically 2x peak heap |
total memory leaked | Any non-zero = real leak |
Hotspot Output Format
hotspot 1: 45.23MB peak in 12,345 allocations with 67,890 temporary allocations
myapp::cache::Cache::insert at src/cache.cpp:142
myapp::request::handle at src/request.cpp:89
std::vector<...>::push_back at ...Reading:
- First line: total bytes at peak, total allocations, temporary count
- Stack trace: top = leaf (where alloc happened), bottom = root caller
Flamegraph from heaptrack
# Generate folded stacks
heaptrack_print -f heaptrack.myapp.*.zst > heaptrack.folded
# Flamegraph by peak allocation (default)
flamegraph.pl --title "Heap Allocations (Peak)" \
--countname bytes \
heaptrack.folded > heap-peak.svg
# Flamegraph by allocation count
heaptrack_print -f -a 100 heaptrack.myapp.*.zst > heaptrack-count.folded
flamegraph.pl --title "Allocation Count" heaptrack-count.folded > heap-count.svg
# View
xdg-open heap-peak.svgCommon Allocation Hotspot Patterns
Pattern: Excessive small allocations
hotspot: 50MB peak in 5,000,000 allocations
std::string::operator= (copying small strings)Fix: Use std::string_view, arena allocator, or SSO-optimised string.
Pattern: Container growth
hotspot: 30MB peak in 100,000 allocations
std::vector::push_back (repeated reallocations)Fix: vec.reserve(expected_size) before push_back loop.
Pattern: Leaked connection/handle
leak: 2MB in 100 allocations
MyConnection::connect at src/conn.cpp:45Fix: Check destructor, ensure RAII wrapper, add unique_ptr.
Pattern: Temporary string allocations
temporary: 10M allocs/sec
std::to_string(int) in hot loopFix: Use fmt::to_string, std::format, or pre-allocated buffer.
Comparing Allocators
# Test with system allocator (baseline)
heaptrack ./myapp > baseline.txt
# Test with jemalloc
LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so heaptrack ./myapp > jemalloc.txt
# Test with mimalloc
LD_PRELOAD=/path/to/libmimalloc.so heaptrack ./myapp > mimalloc.txt
# Compare peak memory
grep "peak heap" baseline.txt jemalloc.txt mimalloc.txtheaptrack GUI (heaptrack_gui)
The Qt-based GUI shows:
- Timeline of heap usage over time
- Flamegraph view (interactive)
- Top allocations table
- Leak view
# Launch GUI
heaptrack_gui heaptrack.myapp.12345.zst
# Or analyse after the fact
heaptrack_gui # File → OpenGUI tabs:
1. Summary: overall stats 2. Bottom-Up: callers → callees (who caused the allocation) 3. Top-Down: callees → callers (allocation call trees) 4. Flame Graph: visual allocation overview 5. Consumed: peak memory timeline
Masif vs heaptrack Quick Command Comparison
| Task | Valgrind massif | heaptrack |
|---|---|---|
| Record | valgrind --tool=massif ./prog | heaptrack ./prog |
| Print summary | ms_print massif.out.* | heaptrack_print -s heap*.zst |
| Print hotspots | `ms_print massif.out.* \ | head` |
| Leaks | valgrind --leak-check=full | heaptrack_print -l heap*.zst |
| GUI | (none built-in) | heaptrack_gui heap*.zst |
| Flamegraph | manual conversion | `heaptrack_print -f heap*.zst \ |