blob: 61cd5264d7a9052d3ae4bd545cd9d8ecec7b17bf [file] [view]
# Android Hprof Dump Data Source
## Overview
A Perfetto data source that triggers a Java heap dump (`.hprof`) on a
target Android process and embeds the raw hprof binary in the trace as
chunked packets. Optionally also extracts bitmap images as PNGs.
This runs in **system_server** (AOSP `frameworks/base`) and uses the
existing `ActivityManagerService.dumpHeap()` mechanism.
## What it does
1. Receives trace config with target process pid/cmdline
2. Calls `AMS.dumpHeap(process, managed=true, dumpBitmaps, path, fd, cb)`
3. Target process runs `Debug.dumpHprofData()` -> `.hprof` file
4. Optionally target process runs `Bitmap.dumpAll("png")` -> PNG files
5. On completion callback: streams file in 512KB chunks as trace packets
6. Cleans up temp files
## Proto
### Config
```proto
// protos/perfetto/config/profiling/hprof_dump_config.proto
message HprofDumpConfig {
optional uint64 pid = 1;
optional string process_cmdline = 2;
optional bool run_gc = 3; // GC before dump, default true
optional bool dump_bitmaps = 4; // also extract bitmaps as PNG
optional string bitmap_format = 5; // "png" (default) or "webp"
}
```
### Trace output
```proto
// protos/perfetto/trace/profiling/hprof_dump.proto
message HprofDump {
optional int32 pid = 1; // target process pid
optional bytes hprof_data = 2; // chunk of raw .hprof binary
optional uint32 chunk_index = 3; // zero-based chunk index
optional bool last_chunk = 4; // true on final chunk for this pid
}
```
The trace processor groups chunks by `pid` and finalizes each dump
when `last_chunk` is received. Multiple dumps (different pids or
sequential same-pid dumps) can coexist in one trace.
## Trace processor
`HprofDumpModule` handles `TracePacket.hprof_dump`:
1. Maintains a per-pid `ArtHprofParser` instance
2. Feeds `hprof_data` chunks via `ArtHprofParser::Parse()`
3. On `last_chunk`: calls `OnPushDataToSorter()` to populate
`heap_graph_class`, `heap_graph_object`, `heap_graph_reference`
4. Any incomplete dumps are finalized at trace end
No new tables -- reuses the existing heap graph infrastructure.
## Chunking
Hprof dumps are typically 200-400MB. The data source streams the file
in 512KB chunks to avoid loading the entire dump into memory. Each
chunk becomes one `TracePacket` with `HprofDump { chunk_index, ... }`.
The final chunk sets `last_chunk = true`.
## Trace config example
```
buffers { size_kb: 524288 } # 512MB for large hprof
data_sources {
config {
name: "android.hprof_dump"
hprof_dump_config {
process_cmdline: "com.example.app"
run_gc: true
dump_bitmaps: true
}
}
}
duration_ms: 60000
```
## Testing
```sh
# Existing mechanism (works today):
adb shell am dumpheap -b png com.example.app /data/local/tmp/dump.hprof
# With Perfetto (after this data source is built):
adb shell perfetto -c - --txt <<EOF
buffers { size_kb: 524288 }
data_sources { config { name: "android.hprof_dump"
hprof_dump_config { process_cmdline: "com.example.app" run_gc: true }
} }
duration_ms: 60000
EOF
```
Load the trace in Perfetto UI -> heap graph tables populated from the
embedded hprof data, alongside any other concurrent trace data.