You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
215 lines
7.5 KiB
215 lines
7.5 KiB
<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>
|
|
|