8

I would like to be able to trigger an Android heap dump from the command line. Is there a command for that?

Specifically, from the command line, not via Montior or DDMS GUIs

Maybe something like using ddms or adb, e.g. ddms -head-dump or adb shell heapdump? AFAICT monitor and ddms always start in GUI mode, and adb doesn't have a heap dump command.

Update: I tried this, it looked promising, but it doesn't work:

  1. adb jdwp
  2. adb forward tcp:8000 jdwp:1234 (substitute output of 1 for 1234)
  3. jmap -dump:format=b,file=heapdump.hprof localhost:8000

But even the heap summary fails:

jmap -heap localhost:8000
Attaching to remote server localhost:8000, please wait...
Error attaching to remote server: java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is: 
        java.net.SocketTimeoutException: Read timed out
nmr
  • 16,625
  • 10
  • 53
  • 67
  • FWIW I was able to connect to the forwarded JDWP port via `jdb -attach localhost:8000` – nmr Sep 11 '14 at 19:44
  • possible duplicate of ["Live" memory analysis tool for Android](http://stackoverflow.com/questions/6483714/live-memory-analysis-tool-for-android) – Damian Leszczyński - Vash Sep 11 '14 at 19:50
  • Nah, that guy is explicitly looking for something that **is not** a heap dump, I am looking a heap dump via command line. – nmr Sep 11 '14 at 19:55
  • The answer under that question uses adb to get the heap dump via kill -11 that triger a full gc and dump of heap in hprof. So what do you mean be heap dump ? – Damian Leszczyński - Vash Sep 11 '14 at 20:01
  • Interesting, unfortunately it looks like as of this commit (https://github.com/android/platform_dalvik/commit/c9dcf262db56d831eb45bb44978a6261e16a2d78?diff=unified) in 2010 (!) SIGUSR1 no longer heap dumps – nmr Sep 11 '14 at 21:08
  • Nope. THe file is missing description i notcied. I linked the proper file in answer. – Damian Leszczyński - Vash Sep 11 '14 at 22:21

3 Answers3

21

In Android pre 3.0 you can use so called

kill -10 <pid> (more)

In Android 3.0 a new command-line tool has been added:

adb shell am dumpheap <pid> <output-file-name>; (more)

Detailed description

To get HPROF you need also change the format of it using hprof-conv

Uma Sankar
  • 449
  • 1
  • 8
  • 19
  • 1
    Wow, awesome, this was really hard to find, thanks. Should be `adb shell am dumpheap ` ("shell" was missing) Worth noting that the out file name has to be user writable, so e.g. write to /sdcard/heapdump.hprof – nmr Sep 11 '14 at 22:28
  • debug is also required – naive Sep 28 '14 at 06:17
  • And output-file-name is optional. The default is `/data/local/tmp/heapdump-- – rds Nov 09 '20 at 19:39
  • pid can also be replaced with package name. – Glorin Oct 27 '22 at 02:57
8

The easy way:

adb shell am dumpheap your.package.name /sdcard/dumpheap.hprof

The hard way (don't remember why I've added it originally):

adb shell am dumpheap $(ps | grep your.package.name | awk '{print $2}') /sdcard/dumpheap.hprof

If your device doesn't have awk try to use busybox awk.

After that pull the created file, convert it with hprof-conv and open it in Android Studio.

0neel
  • 383
  • 5
  • 11
0

For those who do not want each time look for correct PID and just wanna use one-line command

Add this this to your .zshrc or .bashrc:

heap_dump() {
    PACKAGE=$1
    HPROF=/data/local/tmp/$PACKAGE.hprof
    PID=$(adb shell ps | grep $PACKAGE$ | awk '{print $2}')
    out=/Users/$USER/Desktop

    adb shell am dumpheap $PID $HPROF
    adb pull $HPROF $out
}

To use it from command line, connect android with usb and run:

heap_dump my.app.package.name

Heapdump is saved under /Users/$USER/Desktop

Evgenii Vorobei
  • 1,457
  • 18
  • 20