Instant JVM heap dump analysis, right in your browser. No 30-minute indexing wait — results stream in as bytes arrive.
HeapLens is a fast, web-based HPROF heap dump analyzer that starts showing results the moment you upload a file. Class histograms appear in under a second, the full dominator tree builds in the background, and the entire experience runs from a single static binary with zero external dependencies.
Built as a side project to explore streaming heap dump analysis and performance tooling.
Import screen — upload, stream from S3, Kubernetes, or open a server-local path (placeholders only):
Analyzer (example large-heap session): on histogram and dominator, only the left column (class names and object labels) is lightly blurred so aggregate metrics and the rest of the UI stay sharp.
| Overview | Class histogram | Dominator tree |
|---|---|---|
![]() |
![]() |
![]() |
- Instant streaming results — histogram and summary update live as bytes stream in from upload, S3, or Kubernetes
- Dominator tree — object-level retained size analysis with field names and GC root paths
- Object inspector — click any object to see its value, outgoing/incoming references, and shortest GC path
- OQL query language — SQL-like queries on heap objects (e.g.,
SELECT * FROM java.lang.String WHERE retained_size > 1000) - Leak suspects report — MAT-style automatic leak detection with dominator-chain deduplication, cross-suspect adjustment, and dominator paths for each suspect instance
- Thread view — per-thread GC roots with stack traces and retained object correlation
- Export — download histogram, dominator roots, or leak suspects as JSON
- Dark / light theme — toggle in the header, persisted to
localStorage - Archive support — directly analyze
.hprof,.tar,.tar.gz,.tgz, and.gzfiles - Import from anywhere — browser upload, S3 URL, Kubernetes pod, or server-local path
- Single binary — no JVM, no database, no config files
cargo build --release does not put heaplens-cli on your PATH. Use **cargo run** (works the same on Windows, macOS, and Linux) or run the binary from target/release/ directly.
# Build
cargo build --release
# Run
./target/release/heaplens-cli serve --port 8080
# Run without installing — everything after `--` is passed to heaplens-cli
cargo run --release -p heaplens-cli -- analyze /path/to/dump.hprof
cargo run --release -p heaplens-cli -- serve /path/to/dump.hprof --port 8080
cargo run --release -p heaplens-cli -- serve --port 8080Then open http://localhost:8080.
Pre-built multi-arch images (amd64 + arm64) are available on Docker Hub.
# Run with import UI
docker run -p 8080:8080 arunkumarucet/heaplens:0.1.0
# Mount a local dump directory
docker run -p 8080:8080 -v /path/to/dumps:/data arunkumarucet/heaplens:0.1.0
# Build image locally
docker build -t heaplens .To stream a heap dump directly from a Kubernetes pod, mount your kubeconfig and cloud credentials:
docker run --platform=linux/amd64 --rm -p 8080:8080 \
-v "$HOME/.kube/config":/root/.kube/config:ro \
-v "$HOME/.aws":/root/.aws:ro \
-e KUBECONFIG=/root/.kube/config \
-e AWS_PROFILE=your-aws-profile \
arunkumarucet/heaplens:0.1.0Then open http://localhost:8080 and use the Kubernetes import option with pod-name:/path/to/heap.hprof.
docker run -p 8080:8080 \
-e AWS_ACCESS_KEY_ID=... \
-e AWS_SECRET_ACCESS_KEY=... \
-e AWS_REGION=us-east-1 \
arunkumarucet/heaplens:0.1.0# Build Linux static binary
cargo build --release -p heaplens-cli --target x86_64-unknown-linux-musl
# Run analysis inside the pod (no download needed)
./target/x86_64-unknown-linux-musl/release/heaplens-cli k8s my-pod:/tmp/heap.hprof --namespace prod
# Or from dev machine, without PATH:
cargo run --release -p heaplens-cli -- k8s my-pod:/tmp/heap.hprof --namespace prod
# Serve from inside pod + port-forward
cargo run --release -p heaplens-cli -- k8s my-pod:/tmp/heap.hprof --namespace prod --serveheaplens/
parser/ # HPROF parser, object graph, dominator tree, class histogram, OQL, leak suspects
cli/ # Axum web server, web UI, CLI commands, K8s/S3 integration
tools/ # Heap dump generators for testing
- Parser — streaming visitor pattern; zero-copy mmap for local files,
StreamReaderfor pipes - Object graph — CSR (Compressed Sparse Row) adjacency lists; Lengauer-Tarjan dominator algorithm
- Streaming import —
FrontierFileReaderparses files concurrently as they're written by S3/K8s/upload - Two-tier analysis — histogram (fast, streaming) shows instantly; object graph builds in background
- Leak detection — MAT-style class-level aggregation with dominator-chain deduplication to surface only the top-level accumulator classes
Measured on a 5 GB heap dump with ~72M objects:
| Phase | Time |
|---|---|
| Histogram (streaming) | < 1s |
| Pass 2 (reference extraction) | ~60s |
| Dominator tree (Lengauer-Tarjan) | ~25s |
| Retained sizes + sorting | ~15s |
Tested up to 22 GB heap dumps (~450M objects) with streaming parse completing in under 10 minutes. Memory usage is approximately 20-25% of the heap dump size for the analysis data structures. The mmap'd file is released after the object graph is built.
Contributions are welcome! Please open an issue or pull request.
Licensed under the Apache License, Version 2.0. See LICENSE for details.



