DHAT - Dynamic Heap Analysis Tool Cheatsheet
DHAT - Dynamic Heap Analysis Tool Cheatsheet
DHAT (Dynamic Heap Analysis Tool) is a Valgrind tool that answers a different question from most memory profilers. Rather than only “how much memory did you allocate,” it reports how that memory was actually used: blocks that were allocated but never read, blocks written once and never touched again, very short-lived allocations, and allocations far larger than the bytes actually accessed. That usage view often reveals waste that size-only profilers cannot see.
Installation
| Platform | Command |
|---|---|
| Debian/Ubuntu | sudo apt install valgrind |
| Fedora/RHEL | sudo dnf install valgrind |
| Arch Linux | sudo pacman -S valgrind |
| macOS | limited support; prefer Linux |
| Verify | valgrind --tool=dhat --version |
Build your program with
-gfor useful stack traces. DHAT runs under Valgrind, so expect a significant slowdown — this is an analysis tool, not a production profiler.
Running DHAT
valgrind --tool=dhat ./my-program
# → produces dhat.out.<pid>
| Option | Purpose |
|---|---|
--dhat-out-file=FILE | Output path |
--mode=heap | Default heap profiling |
--mode=copy | Profile memory copying (memcpy etc.) |
--mode=ad-hoc | Custom instrumentation points |
--num-callers=N | Stack depth in reports |
Viewing Results
DHAT output is JSON, viewed in the bundled HTML viewer:
# Open the viewer and load dhat.out.<pid>
firefox /usr/libexec/valgrind/dh_view.html
| UI element | Shows |
|---|---|
| Tree of allocation points | Grouped by call stack |
| Total / max bytes | Volume per site |
| Reads / writes | How much the memory was actually accessed |
| Lifetimes | How long blocks lived |
| Sorting | By any metric to find the worst offenders |
The Metrics That Matter
| Metric | Reveals |
|---|---|
| Total bytes | Overall allocation volume from this site |
| Max bytes | Peak simultaneous usage |
| Reads / writes | Access intensity |
| Reads = 0 | Allocated but never read — pure waste |
| Writes = 0 | Never initialized — likely a bug or waste |
| Short lifetimes | Churn; candidates for stack/pooling |
| Access ratio | Bytes accessed vs bytes allocated |
The “reads = 0” case is the classic DHAT find: memory a program dutifully allocates, fills, and frees without anything ever reading it.
Common Findings and Fixes
| Finding | Likely fix |
|---|---|
| Many tiny short-lived allocations | Stack allocation, arena, or object pool |
| Large block, tiny accessed portion | Allocate only what you use; lazy load |
| Never-read allocations | Delete the work entirely |
| Repeated alloc/free of same size | Reuse a buffer |
| Oversized containers | Reserve accurate capacity |
Copy Mode
valgrind --tool=dhat --mode=copy ./my-program
Copy mode profiles memcpy/memmove volume by call site — useful when profiling shows time in copying and you need to know which code is responsible.
Ad-Hoc Mode
Ad-hoc mode lets you count arbitrary events by annotating your code with DHAT client requests, turning DHAT into a general “which call stack does this the most” counter.
DHAT vs Related Tools
| Aspect | DHAT | massif | heaptrack | Bytehound |
|---|---|---|---|---|
| Focus | How memory is used | Peak usage over time | Allocation profiling | Interactive exploration |
| Overhead | High (Valgrind) | High (Valgrind) | Low | Low |
| Unique insight | Unread/underused blocks | Peak snapshots | Churn + leaks | Rich filtering |
| Best for | Finding wasted work | Peak reduction | Fast realistic runs | Deep interactive analysis |
Use heaptrack or Bytehound for low-overhead profiling of realistic runs; reach for DHAT when you want to know whether allocated memory was ever actually used.