tree: 579d93af4c86ea7bbff86184413ebd0e0ab28da0
  1. HprofDumpDataSource.java
  2. INTEGRATION.md
  3. README.md
src/java_datasource/android_hprof_bitmaps/README.md

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

// 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

// 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

# 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.