blob: 3c80b4ada22ed714ff0037b90f36d1ec9dff9d91 [file] [log] [blame]
Andy McFaddenaa336022009-04-27 13:19:51 -07001<html>
2<head>
3 <title>Dalvik Heap Profiling</title>
4</head>
5
6<body>
7<h1>Dalvik Heap Profiling</h1>
8
9<p>
10The Dalvik virtual machine can produce a complete dump of the contents
11of the virtual heap. This is very useful for debugging memory usage
12and looking for memory leaks. Getting at the information can be tricky,
13but has become easier in recent releases.
14
15
16<h2>Getting the data</h2>
17<p>
18The first step is to cause the VM to dump its status, and then pull the hprof
19data off. The exact manner for doing so has changed over time.
20</p><p>
21There is a <code>runhat</code> shell function, added by
22<code>build/envsetup.sh</code>, that partially automates these steps. The
23function changes in each release to accommodate newer behavior, so you have
24to be careful that you don't use the wrong version.
25</p><p>
26
27<h3>Early releases (1.0/1.1)</h3>
28<p>
29You can only generate heap data on the emulator or a device with root
30access, because of the way the dump is initiated and where the output
31files go.
32</p><p>
33Get a command shell on the device:
34<blockquote><pre>
35$ adb shell
36</pre></blockquote>
37</p><p>
38You can verify that you're running as root with the <code>id</code> command.
39The response should look like <code>uid=0(root) gid=0(root)</code>. If not,
40type <code>su</code> and try again. If <code>su</code> fails, you're out
41of luck.
42
43</p><p>
44Next, ensure the target directory exists:
45<blockquote><pre>
46# mkdir /data/misc
47# chmod 777 /data/misc
48</pre></blockquote>
49
50</p><p>
51Use <code>ps</code> or DDMS to determine the process ID of your application,
52then send a <code>SIGUSR1</code> to the target process:
53
54<blockquote><pre>
55# kill -10 &lt;pid&gt;
56</pre></blockquote>
57
58</p><p>
59The signal causes a GC, followed by the heap dump (to be completely
60accurate, they actually happen concurrently, but the results in the heap
61dump reflect the post-GC state). This can take a couple of seconds,
62so you have to watch for the GC log message to know when it's complete.
63</p><p>
64Next:
65
66<blockquote><pre>
67# ls /data/misc/heap-dump*
68# exit
69</pre></blockquote>
70
71</p><p>
72Use <code>ls</code> to check the file names, then <code>exit</code> to quit
73the device command shell.
74
75</p><p>
76You should see two output files, named
77<code>/data/misc/heap-dump-BLAH-BLAH.hprof</code> and
78<code>.hprof-head</code>, where BLAH is a runtime-generated value
79that ensures the filename is unique. Pull them off of the device and
80remove the device-side copy:
81
82<blockquote><pre>
83$ adb pull /data/misc/heap-dump-BLAH-BLAH.hprof tail.hprof
84$ adb pull /data/misc/heap-dump-BLAH-BLAH.hprof-head head.hprof
85$ adb shell rm /data/misc/heap-dump-BLAH-BLAH.hprof /data/misc/heap-dump-BLAH-BLAH.hprof-head
86</pre></blockquote>
87
88</p><p>
89Merge them together and remove the intermediates:
90
91<blockquote><pre>
92$ cat head.hprof tail.hprof &gt; dump.hprof
93$ rm head.hprof tail.hprof
94</pre></blockquote>
95
96</p><p>
97You now have the hprof dump in <code>dump.hprof</code>.
Andy McFaddenaa336022009-04-27 13:19:51 -070098</p><p>
99
100
Andy McFaddenc7659ec2009-09-18 16:14:41 -0700101<h3>Android 1.5 ("Cupcake")</h3>
Andy McFaddenaa336022009-04-27 13:19:51 -0700102<p>
103Some steps were taken to make this simpler. Notably, the two output
104files are now combined for you, and a new API call was added that allows
105a program to write the dump at will to a specific file. If you're not
106using the API call, you still need to be on an emulator or running as root.
107(For some builds, you can use <code>adb root</code> to restart the adb
108daemon as root.)
109</p><p>
110The basic procedure is the same as for 1.0/1.1, but only one file will
111appear in <code>/data/misc</code> (no <code>-head</code>), and upon
112completion you will see a log message that says "hprof: heap dump completed".
113It looks like this in the log:
114
115<blockquote><pre>
116I/dalvikvm( 289): threadid=7: reacting to signal 10
117I/dalvikvm( 289): SIGUSR1 forcing GC and HPROF dump
118I/dalvikvm( 289): hprof: dumping VM heap to "/data/misc/heap-dump-tm1240861355-pid289.hprof-hptemp".
119I/dalvikvm( 289): hprof: dumping heap strings to "/data/misc/heap-dump-tm1240861355-pid289.hprof".
120I/dalvikvm( 289): hprof: heap dump completed, temp file removed
121</pre></blockquote>
122
123</p><p>
124Summary: as above, use <code>mkdir</code> and <code>chmod</code>
125to ensure the directory exists and is writable by your application.
126Send the <code>SIGUSR1</code> or use the API call to initiate a dump.
127Use <code>adb pull &lt;dump-file&gt;</code> and <code>adb shell rm
128&lt;dump-file&gt;</code> to retrieve the file and remove it from the
129device. The concatenation step is not needed.
130
131</p><p>
132The new API is in the <code>android.os.Debug</code> class:
133<blockquote><pre>
134public static void dumpHprofData(String fileName) throws IOException
135</pre></blockquote>
136When called, the VM will go through the same series of steps (GC and
137generate a .hprof file), but the output will be written to a file of
138your choice, e.g. <code>/sdcard/myapp.hprof</code>. Because you're
139initiating the action from within the app, and can write the file to
140removable storage or the app's private data area, you can do this on a
141device without root access.
142
143
Andy McFaddenc7659ec2009-09-18 16:14:41 -0700144<h3>Android 1.6 ("Donut")</h3>
145<p>
Andy McFadden0998df52009-11-20 13:42:29 -0800146No real change to the way profiling works.
147However, 1.6 introduced the <code>WRITE_EXTERNAL_STORAGE</code>
148permission, which is required to write data to the SD card. If you're
149accustomed to writing profile data to <code>/sdcard</code>, you will
150need to enable the permission in your application's manifest.
151
152
153<h3>Android 2.0 ("Eclair")</h3>
154<p>
155In 2.0, features were added that allow DDMS to request a heap dump on
Andy McFaddenc7659ec2009-09-18 16:14:41 -0700156demand, and automatically pull the result across. Select your application
Andy McFadden0998df52009-11-20 13:42:29 -0800157and click the "dump HPROF file" button in the top left. This always
158writes files to the SD card, so
Andy McFaddenc7659ec2009-09-18 16:14:41 -0700159you must have a card inserted and the permission enabled in your application.
Andy McFaddenc7659ec2009-09-18 16:14:41 -0700160
161
Andy McFaddenaa336022009-04-27 13:19:51 -0700162<h2>Examining the data</h2>
163<p>
164The data file format was augmented slightly from the common hprof format,
165and due to licensing restrictions the modified <code>hat</code> tool cannot
166be distributed. A conversion tool, <code>hprof-conv</code>, can be used
167to strip the Android-specific portions from the output. This tool was
168first included in 1.5, but will work with older versions of Android.
169</p><p>
170The converted output should work with any hprof data analyzer, including
171<code>jhat</code>, which is available for free in the Sun JDK, and
172Eclipse MAT.
173
174<!-- say something about how to track down common problems, interesting
175 things to look for, ...? -->
176
Andy McFadden842e20c2009-04-30 14:12:27 -0700177</p><p>
178<address>Copyright &copy; 2009 The Android Open Source Project</address>
179
Andy McFaddenaa336022009-04-27 13:19:51 -0700180</body>
181</html>