| <html> |
| <head> |
| <title>Dalvik Heap Profiling</title> |
| </head> |
| |
| <body> |
| <h1>Dalvik Heap Profiling</h1> |
| |
| <p> |
| The Dalvik virtual machine can produce a complete dump of the contents |
| of the virtual heap. This is very useful for debugging memory usage |
| and looking for memory leaks. Getting at the information can be tricky, |
| but has become easier in recent releases. |
| </p><p> |
| In what follows, the version number refers to the software release |
| running on the phone. To take advantage of the DDMS integration, you will |
| also need a sufficiently recent version of DDMS. |
| |
| |
| <h2>Getting the data</h2> |
| <p> |
| The first step is to cause the VM to dump its status, and then pull the hprof |
| data off. The exact manner for doing so has changed over time. |
| </p><p> |
| There is a <code>runhat</code> shell function, added by |
| <code>build/envsetup.sh</code>, that partially automates these steps. The |
| function changes in each release to accommodate newer behavior, so you have |
| to be careful that you don't use the wrong version. |
| </p><p> |
| |
| <h3>Early releases (1.0/1.1)</h3> |
| <p> |
| You can only generate heap data on the emulator or a device with root |
| access, because of the way the dump is initiated and where the output |
| files go. |
| </p><p> |
| Get a command shell on the device: |
| <blockquote><pre> |
| $ adb shell |
| </pre></blockquote> |
| </p><p> |
| You can verify that you're running as root with the <code>id</code> command. |
| The response should look like <code>uid=0(root) gid=0(root)</code>. If not, |
| type <code>su</code> and try again. If <code>su</code> fails, you're out |
| of luck. |
| |
| </p><p> |
| Next, ensure the target directory exists: |
| <blockquote><pre> |
| # mkdir /data/misc |
| # chmod 777 /data/misc |
| </pre></blockquote> |
| |
| </p><p> |
| Use <code>ps</code> or DDMS to determine the process ID of your application, |
| then send a <code>SIGUSR1</code> to the target process: |
| |
| <blockquote><pre> |
| # kill -10 <pid> |
| </pre></blockquote> |
| |
| </p><p> |
| The signal causes a GC, followed by the heap dump (to be completely |
| accurate, they actually happen concurrently, but the results in the heap |
| dump reflect the post-GC state). This can take a couple of seconds, |
| so you have to watch for the GC log message to know when it's complete. |
| </p><p> |
| Next: |
| |
| <blockquote><pre> |
| # ls /data/misc/heap-dump* |
| # exit |
| </pre></blockquote> |
| |
| </p><p> |
| Use <code>ls</code> to check the file names, then <code>exit</code> to quit |
| the device command shell. |
| |
| </p><p> |
| You should see two output files, named |
| <code>/data/misc/heap-dump-BLAH-BLAH.hprof</code> and |
| <code>.hprof-head</code>, where BLAH is a runtime-generated value |
| that ensures the filename is unique. Pull them off of the device and |
| remove the device-side copy: |
| |
| <blockquote><pre> |
| $ adb pull /data/misc/heap-dump-BLAH-BLAH.hprof tail.hprof |
| $ adb pull /data/misc/heap-dump-BLAH-BLAH.hprof-head head.hprof |
| $ adb shell rm /data/misc/heap-dump-BLAH-BLAH.hprof /data/misc/heap-dump-BLAH-BLAH.hprof-head |
| </pre></blockquote> |
| |
| </p><p> |
| Merge them together and remove the intermediates: |
| |
| <blockquote><pre> |
| $ cat head.hprof tail.hprof > dump.hprof |
| $ rm head.hprof tail.hprof |
| </pre></blockquote> |
| |
| </p><p> |
| You now have the hprof dump in <code>dump.hprof</code>. |
| </p><p> |
| |
| |
| <h3>Android 1.5 ("Cupcake")</h3> |
| <p> |
| Some steps were taken to make this simpler. Notably, the two output |
| files are now combined for you, and a new API call was added that allows |
| a program to write the dump at will to a specific file. If you're not |
| using the API call, you still need to be on an emulator or running as root. |
| (For some builds, you can use <code>adb root</code> to restart the adb |
| daemon as root.) |
| </p><p> |
| The basic procedure is the same as for 1.0/1.1, but only one file will |
| appear in <code>/data/misc</code> (no <code>-head</code>), and upon |
| completion you will see a log message that says "hprof: heap dump completed". |
| It looks like this in the log: |
| |
| <blockquote><pre> |
| I/dalvikvm( 289): threadid=7: reacting to signal 10 |
| I/dalvikvm( 289): SIGUSR1 forcing GC and HPROF dump |
| I/dalvikvm( 289): hprof: dumping VM heap to "/data/misc/heap-dump-tm1240861355-pid289.hprof-hptemp". |
| I/dalvikvm( 289): hprof: dumping heap strings to "/data/misc/heap-dump-tm1240861355-pid289.hprof". |
| I/dalvikvm( 289): hprof: heap dump completed, temp file removed |
| </pre></blockquote> |
| |
| </p><p> |
| Summary: as above, use <code>mkdir</code> and <code>chmod</code> |
| to ensure the directory exists and is writable by your application. |
| Send the <code>SIGUSR1</code> or use the API call to initiate a dump. |
| Use <code>adb pull <dump-file></code> and <code>adb shell rm |
| <dump-file></code> to retrieve the file and remove it from the |
| device. The concatenation step is not needed. |
| |
| </p><p> |
| The new API is in the <code>android.os.Debug</code> class: |
| <blockquote><pre> |
| public static void dumpHprofData(String fileName) throws IOException |
| </pre></blockquote> |
| When called, the VM will go through the same series of steps (GC and |
| generate a .hprof file), but the output will be written to a file of |
| your choice, e.g. <code>/sdcard/myapp.hprof</code>. Because you're |
| initiating the action from within the app, and can write the file to |
| removable storage or the app's private data area, you can do this on a |
| device without root access. |
| |
| |
| <h3>Android 1.6 ("Donut")</h3> |
| <p> |
| No real change to the way profiling works. |
| However, 1.6 introduced the <code>WRITE_EXTERNAL_STORAGE</code> |
| permission, which is required to write data to the SD card. If you're |
| accustomed to writing profile data to <code>/sdcard</code>, you will |
| need to enable the permission in your application's manifest. |
| </p> |
| |
| |
| <h3>Android 2.0 ("Eclair")</h3> |
| <p> |
| In 2.0, features were added that allow DDMS to request a heap dump on |
| demand, and automatically pull the result across. Select your application |
| and click the "dump HPROF file" button in the top left. This always |
| writes files to the SD card, so |
| you must have a card inserted and the permission enabled in your application. |
| </p> |
| |
| |
| <h3>Android 2.2 ("Froyo")</h3> |
| <p> |
| DDMS heap dump requests are now streamed directly out of the VM, removing |
| the external storage requirement. |
| </p> |
| |
| <h3>Android 2.3 ("Gingerbread")</h3> |
| <p> |
| The <code>kill -10</code> (<code>SIGUSR1</code>) method of generating heap |
| dumps has been removed from the VM. |
| </p> |
| |
| <h3>Android 3.0 ("Honeycomb")</h3> |
| <p> |
| A new command-line tool has been added: |
| </p> |
| <blockquote><pre>am dumpheap <pid> <output-file-name></pre></blockquote> |
| <p> |
| Unlike the <code>SIGUSR1</code> approach, this does not require a rooted |
| phone. It's only necessary for the application to be debuggable (by setting |
| <code>android:debuggable="true"</code> in the <code><application></code> |
| element of the app manifest). The output file is opened by "am", which |
| means you can write the data to a file on <code>/sdcard</code> without |
| needing the <code>WRITE_EXTERNAL_STORAGE</code> permission in your app. |
| <p> |
| The <code>runhat</code> shell function has been updated to use this. |
| </p> |
| |
| <h2>Examining the data</h2> |
| <p> |
| The data file format was augmented slightly from the common hprof format, |
| and due to licensing restrictions the modified <code>hat</code> tool cannot |
| be distributed. A conversion tool, <code>hprof-conv</code>, can be used |
| to strip the Android-specific portions from the output. This tool was |
| first included in 1.5, but will work with older versions of Android. |
| </p><p> |
| The converted output should work with any hprof data analyzer, including |
| <code>jhat</code>, which is available for free in the Sun JDK, and |
| Eclipse MAT. |
| |
| <!-- say something about how to track down common problems, interesting |
| things to look for, ...? --> |
| |
| </p><p> |
| <address>Copyright © 2009 The Android Open Source Project</address> |
| |
| </body> |
| </html> |