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.
AMS.dumpHeap(process, managed=true, dumpBitmaps, path, fd, cb)Debug.dumpHprofData() -> .hprof fileBitmap.dumpAll("png") -> PNG files// 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" }
// 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.
HprofDumpModule handles TracePacket.hprof_dump:
ArtHprofParser instancehprof_data chunks via ArtHprofParser::Parse()last_chunk: calls OnPushDataToSorter() to populate heap_graph_class, heap_graph_object, heap_graph_referenceNo new tables -- reuses the existing heap graph infrastructure.
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.
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
# 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.