A specialized command-line tool for deep-diving into Go heap profiles (pprof).
This analyzer goes beyond standard pprof tools by applying heuristics to detect common memory anti-patterns, potential leaks, and high-pressure allocation hotspots.
This tool parses a standard pprof heap profile and generates a 7-section unified report:
- Anti-Pattern Detection: Automatically flags common mistakes (e.g.,
time.Afterin loops, heavy JSON reflection, unoptimized slice growth). - Hot Lines: Pinpoints the exact file and line number responsible for the most allocations.
- Business Logic Context: aggregates data by pprof labels (if present) to show cost per request/worker/context.
- Top Object Producers: Identifies functions creating the most garbage (GC pressure), calculated by allocation count and average object size.
- Leak Candidates: Highlights functions with high "In-Use" memory but low "Allocated" throughput—a strong signal for memory leaks or unbounded caches.
- Root Cause Traces: Displays the call stack for the top 5 heavy allocators to show who is calling the expensive function.
- ASCII Flame Graph: Visualizes the call tree directly in your terminal for paths consuming >1% of memory.
You can run the tool directly or build it as a binary.
make memcheck
memcheck <path-to-heap-profile.pb.gz>
Or run directly with go run:
go run main.go heap.pb.gz
Note: You must provide a standard Go heap profile (proto format). You can generate one from a running Go app using:
curl -o heap.pb.gz http://localhost:6060/debug/pprof/heap
Checks your profile against a list of known Go performance pitfalls:
- Loop Timer Leak: Misuse of
time.Afterinside loops. - Repeated RegEx:
regexp.Compileappearing in hot paths. - Heavy JSON: Excessive allocation in
json.Unmarshal. - Interface Boxing: High cost of converting concrete types to
interface{}. - Slice/Map Growth: High allocations in
growsliceormapassign(suggests missing capacity pre-allocation).
Shows the exact source code location (File:Line) for the top allocators. This is often more useful than function names alone.
If your application uses pprof labels (e.g., pprof.Do), this section breaks down memory usage by those labels (e.g., per HTTP route or background worker ID).
Focuses on GC Pressure. Functions listed here churn through many small objects, causing the Garbage Collector to run frequently, even if total memory usage is low.
Focuses on RAM Usage. Lists functions that allocate memory that stays allocated.
- High In-Use %: Suggests a cache, global variable, or memory leak.
- Diagnosis: The tool provides specific advice (e.g., "Unbounded Map?", "Check capacity reset") based on the ratio of In-Use vs. Allocated bytes.
For the top 5 allocators, this prints the stack trace up to the root. It attempts to tag the "Likely Cause" by skipping standard library functions to find your code.
A text-based tree view of memory consumption.
├──indicates a child call.- Shows total bytes and percentage of heap for that path.
- Hides paths contributing <1% to reduce noise.