Of course! Using Python to automate adb dumpheap is a powerful technique for Android performance analysis, especially for memory profiling and debugging memory leaks.

Here's a comprehensive guide covering everything from the basic setup to a complete, production-ready Python script.
Prerequisites
Before you start, ensure you have the necessary tools:
- Python: Installed on your system.
- Android SDK Platform-Tools: This includes the
adb(Android Debug Bridge) executable.- Download: Get it from the official Android Developers website.
- Add to PATH: Make sure the
adbexecutable is in your system's PATH so you can run it from anywhere.
- Rooted Android Device (Optional but Recommended):
dumpheaprequires theDUMPpermission, which is typically only available to system apps or root users.- Non-Rooted: You can only dump the heap of your own app if it has the
android.permission.DUMPpermission declared in its manifest. This is rare for standard apps. - Rooted: You can use
adb shell su -c "..."to run the command with root privileges, allowing you to dump the heap of any app process.
Understanding the adb dumpheap Command
The core command you'll be wrapping in Python is:
adb shell dumpheap <pid> <output_file.hprof>
<pid>: The Process ID of the target application. You can find this usingadb shell ps.<output_file.hprof>: The path on the device where the heap dump will be saved. A common location is/sdcard/.- Note: The
.hproffile format is the standard for Android heap dumps. It can be analyzed by tools like Android Studio's Profiler, MAT (Memory Analyzer Tool), orhprof-conv.
The Python Script: A Step-by-Step Guide
Let's build a robust Python script that automates the entire process: finding the PID, dumping the heap, pulling the file to your computer, and cleaning up.

Step 1: Install a Helper Library
The subprocess module is built-in, but shlex makes handling shell arguments with spaces much safer. We'll also use psutil for a more reliable way to find the PID on the host machine if the app is running.
pip install psutil
Step 2: The Complete Python Script
Here is a well-commented, reusable script. Save it as dump_heap.py.
import subprocess
import shlex
import time
import os
import sys
import argparse
import psutil # For finding the PID on the host machine
# --- Configuration ---
# A common place to store heap dumps on your computer
LOCAL_DUMP_DIR = "heap_dumps"
# A common place to store heap dumps on the Android device
REMOTE_DUMP_DIR = "/sdcard/"
def run_adb_command(command):
"""Executes an adb command and returns its output."""
try:
# shlex.split handles arguments with spaces correctly
cmd = shlex.split(command)
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
return result.stdout.strip()
except subprocess.CalledProcessError as e:
print(f"Error executing ADB command: {e}")
print(f"STDERR: {e.stderr}")
return None
def find_app_pid(package_name):
"""
Finds the PID of an Android app using its package name.
Tries to find it on the host machine first (more reliable), then falls back to adb.
"""
# Try to find the process on the host machine (works if ADB is in port forwarding mode)
for proc in psutil.process_iter(['pid', 'name']):
try:
# The command line for an ADB-connected process often contains the package name
if package_name.lower() in proc.info['name'].lower():
print(f"Found PID {proc.info['pid']} on host for package '{package_name}'.")
return str(proc.info['pid'])
except (psutil.NoSuchProcess, psutil.AccessDenied):
continue
# Fallback to the traditional 'adb shell ps' method
print(f"Host search failed. Falling back to 'adb shell ps' for package '{package_name}'.")
ps_output = run_adb_command("adb shell ps")
if not ps_output:
return None
for line in ps_output.splitlines():
# Example line: u0_a100 12345 1234 1080000 SyS_epoll_0 com.example.myapp
parts = line.split()
if package_name in parts:
pid = parts[1]
print(f"Found PID {pid} on device for package '{package_name}'.")
return pid
print(f"Could not find PID for package: {package_name}")
return None
def dump_heap(package_name):
"""
Main function to dump the heap of a given package.
"""
print(f"--- Starting heap dump for package: {package_name} ---")
# 1. Find the Process ID (PID)
pid = find_app_pid(package_name)
if not pid:
return False
# 2. Define the remote and local file paths
remote_file_path = f"{REMOTE_DUMP_DIR}heapdump_{pid}_{int(time.time())}.hprof"
local_file_path = f"{LOCAL_DUMP_DIR}/{os.path.basename(remote_file_path)}"
# 3. Create local directory if it doesn't exist
os.makedirs(LOCAL_DUMP_DIR, exist_ok=True)
# 4. Execute the dumpheap command on the device
# Using 'su -c' is required for non-system apps on non-rooted devices,
# and is necessary for dumping other apps' heaps on rooted devices.
# The 'am dumpheap' command is a modern alternative but requires the DUMP permission.
dump_command = f"adb shell su -c \"dumpheap {pid} {remote_file_path}\""
print(f"Executing: {dump_command}")
# Note: This command can hang if the process is unresponsive.
# A timeout could be added here.
stdout = run_adb_command(dump_command)
if stdout is None:
print("Heap dump command failed.")
return False
print("Heap dump command sent successfully. Waiting for file to be created...")
time.sleep(2) # Give the device a moment to write the file
# 5. Pull the .hprof file from the device to your computer
pull_command = f"adb pull {remote_file_path} {local_file_path}"
print(f"Executing: {pull_command}")
stdout = run_adb_command(pull_command)
if stdout is None:
print("Failed to pull heap dump file.")
return False
print(f"Successfully pulled heap dump to: {local_file_path}")
# 6. Clean up: Remove the heap dump from the device
# Note: Be careful with 'rm' commands. It's better practice to use 'rm -f'.
rm_command = f"adb shell rm {remote_file_path}"
print(f"Executing: {rm_command}")
run_adb_command(rm_command) # We don't care if this fails, but we try.
print("Cleaned up remote file.")
print(f"--- Heap dump complete for {package_name} ---")
return True
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Automate ADB heap dump for an Android app.")
parser.add_argument("package_name", help="The package name of the app (e.g., com.example.myapp)")
args = parser.parse_args()
if dump_heap(args.package_name):
sys.exit(0)
else:
sys.exit(1)
Step 3: How to Use the Script
-
Save the code: Save the script above as
dump_heap.py. -
Connect your device: Make sure your Android device is connected via USB and USB debugging is enabled.
-
Run from the terminal:
python dump_heap.py com.example.myapp
Replace
com.example.myappwith the actual package name of the app you want to analyze.
Step 4: Analyze the Output
After the script runs, you will find a .hprof file in the heap_dumps directory (e.g., heap_dumps/heapdump_12345_1678886400.hprof).
You can now open this file with professional memory analysis tools:
- Android Studio Profiler: The easiest way. Just open the Profiler tab and import the
.hproffile. - Eclipse MAT (Memory Analyzer Tool): A powerful, standalone tool for analyzing heap dumps. It can find memory leaks, duplicate objects, and more.
- LeakCanary: While primarily a runtime library, it can also be configured to analyze
.hproffiles.
Troubleshooting Common Issues
-
adb: command not found- Solution: The Android SDK Platform-Tools are not in your system's PATH. Add the directory containing
adb.exe(Windows) oradb(macOS/Linux) to your PATH environment variable.
- Solution: The Android SDK Platform-Tools are not in your system's PATH. Add the directory containing
-
error: no devices/emulators found- Solution: Ensure your device is connected, USB debugging is enabled in the Developer options, and you've approved the computer's RSA key on your phone.
-
dumpheap: permission denied- Cause: You are trying to dump a process you don't have permission for.
- Solution 1 (Rooted Device): The script already uses
adb shell su -c "...". Ensure your device is properly rooted and that ADB has root access (you might need to useadb rootfirst, or grant root access via SuperSU/Superuser app when prompted). - Solution 2 (Non-Rooted): You can only dump your own app if it has the
DUMPpermission. This is not feasible for most users. Rooting is the most reliable way for general-purpose heap dumping.
-
Can't find PID- Cause: The app is not running, or the package name is incorrect.
- Solution: Double-check the package name. You can list all running apps with
adb shell pm list packages -fand find the one corresponding to your app. Ensure the app is open and active on the device.
-
The operation timed out- Cause: The
dumpheapprocess can take a long time on apps with large heaps, or it might be hanging. - Solution: Increase the sleep time in the script after the dump command. If it still hangs, you may need to manually intervene or investigate why the target process is unresponsive. You can add a
timeoutparameter to thesubprocess.runcall if you want the script to kill the command after a certain period.
- Cause: The
