216 lines
7.5 KiB
HTML
216 lines
7.5 KiB
HTML
<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>
|